闭包:(返回函数的行为叫闭包??)
1 #函数也是对象,所以可以被传递 2 def line_conf(a,b): 3 def line(x): 4 return a*x+b 5 return line 6 7 line1=line_conf(1,1) 8 line2=line_conf(4,5) 9 print(line1,line2) 10 11 #闭包:包含有环境变量取值的函数对象 12 #函数line与环境变量a,b构成闭包 13 #通过闭包,得到直线表达函数 y=x+1 y=4x+5
<function line_conf.<locals>.line at 0x00000000026FA9D8> <function line_conf.<locals>.line at 0x00000000026FAB70>
@修饰符(装饰器):
函数可以赋值给变量,变量可以调用函数:
def now(): print("2017-12-21") f=now print(f) f()
<function now at 0x00000000020FCBF8>
2017-12-21
如果要增强now函数的功能,但不改变now函数的定义,可以在程序执行的时候,通过装饰器给函数增强功能。这种方法叫做:装饰器(Decorator)。
比如,新增的功能是打印
作为装饰器的打印函数,本质上是个返回函数的高阶函数:
def log(func): def wrapper(*args,**kw): print('call %s():' % func.__name__) return func(*args,**kw) return wrapper @log def now(): print("2017-12-21") now()
call now():
2017-12-21
1 def makebold(fn): 2 def wrapped(): 3 return "<b>"+fn()+"</b>" 4 return wrapped 5 6 def makeitalic(fn): 7 def wrapped(): 8 return "<i>" +fn()+"</i>" 9 return wrapped 10 11 @makebold 12 @makeitalic 13 def hello(): 14 return "hello world" 15 16 print(hello())
<b><i>hello world</i></b>
1 #带参数的装饰器 2 3 def makebold(pre=""): 4 def printMakeBold(fn): 5 def wrapped(): 6 print(pre) 7 return "<b>"+fn()+"</b>" 8 return wrapped 9 return printMakeBold 10 11 @makebold("测试") 12 def printfn(): 13 return "helloworld" 14 15 print(printfn())
测试
<b>helloworld</b>
1 #装饰器用于类 2 3 def decorator(aClass): 4 class newClass: 5 def __init__(self,age): 6 self.total_display=0 7 self.wrapped=aClass(age) 8 def display(self): 9 self.total_display+=1 10 print("total display",self.total_display) 11 return newClass 12 13 @decorator 14 class Bird: 15 def __init__(self,age): 16 self.age=age 17 def display(self): 18 print("my age is",self.age) 19 20 eagleLord=Bird(5) 21 for i in range(3): 22 eagleLord.display() 23 24 # 在decorator中,我们返回了一个新类newClass。在新类中,我们记录了原来类生成的对象(self.wrapped),并附加了新的属性total_display,用于记录调用display的次数。我们也同时更改了display方法。 25 # 26 # 27 # 通过修改,我们的Bird类可以显示调用display的次数了。
total display 1
total display 2
total display 3