闭包
如果在一个内部函数(函数里的函数)里,对在外部作用域(但不是在全局作用域,可以理解为外层函数)的变量进行引用,那么内部函数就被认为是闭包。
例如:
def outer(): x=10 # 这里x即为外部作用域变量 def inner(): print(x) return inner # inner函数被称为一个闭包
装饰器
写python代码一定要遵循开放封闭原则。即,可扩展功能,对源代码修改是封闭的。装饰是为函数和类指定管理代码的一种方式。装饰器本身的形式是处理其他的可调用对象的可调用的对象(如函数)。它们主要只是一种语法糖。
装饰器有两个原则:不改变原来函数的调用方法;不改变原来函数的源代码。
注:根据我自己的实验,递归函数尽量不要使用装饰器,否则会函数嵌套函数,出现各种bug;比如斐波那契函数: import time # 为函数增加 统计执行时长 def show_time(func): def inner(n): start_time=time.time() func(n) end_time=time.time() print("takes %d s"%(end_time-start_time)) return func(n) return inner #********************** @show_time def fibo(n): if 1 < n <= 3: return 1 elif n==1: return 0 elif n<=0: return "please input an int greater than 0." return fibo(n-1)+fibo(n-2) print(fibo(31)) #*********************** 星号这部分就会有问题 @show_time def fib(n): a = 0 b = 1 if n >= 3: for i in range(n+1)[3:]: a,b=b,a+b result = b return result elif n == 1: return a elif n ==2: return b else: return "please input an int greater than 0." print(fib(80000)) # for循环的就没有问题
装饰器支持嵌套:
@A
@B
def C():
print("in the c")
python装饰器有两种形式:
- 函数装饰器在函数定义的时候进行名称重绑定,提供一个逻辑层来管理函数和方法或随后对它们的调用。
- 类装饰器在类定义的时候进行名称重绑定,提供一个逻辑层来管理类,或管理随后调用它们所创建的示例。
装饰器举例:
import time def show_time(func): def inner(): start_time=time.time() func() end_time=time.time() print("takes %d s"%(end_time-start_time)) return inner @show_time # 等于 foo=show_time(foo) def foo(): print("in the foo.") print("foo...") time.sleep(3) @show_time # 等于 bar=show_time(bar) def bar(): print("in the bar.") print("bar...") time.sleep(2)
装饰器参数:给装饰器加参数。还以上面例子来说,给bar函数加上日志记录,foo函数不加。
import time def logger(flag='false'): def show_time(func): def inner(): start_time=time.time() func() end_time=time.time() print("takes %d s"%(end_time-start_time)) if flag == 'true': print("write logs...") return inner return show_time #@show_time # 等于 foo=show_time(foo) @logger() def foo(): print("in the foo.") print("foo...") time.sleep(3) #@show_time # 等于 bar=show_time(bar) @logger('true') def bar(): print("in the bar.") print("bar...") time.sleep(2)