装饰器:
给一个现有函数增加功能,保证参数的正确传递。
以面向对象的方式封装:
def add(x,y): print('Cala: %s +%s='%(x,y),end='') return x + y class MyCounter: def __init__(self,f): self.func=f self.count=0 def __call__(self, *args, **kwargs): self.count+=1 return self.func(*args,**kwargs) myadd=MyCounter(add) #myadd(1,2) print(myadd(1,2))
以函数的方式封装:
def add(x,y): print('Cala: %s +%s='%(x,y),end='') return x + y def my_counter(f): def wapper(*args,**kwargs): wapper.counter+=1 return f(*args,**kwargs) wapper.counter=0 return wapper myadd=my_counter(add) print(myadd(1,2))
装饰器语法:
def my_counter(f): def wapper(*args,**kwargs): wapper.counter+=1 return f(*args,**kwargs) wapper.counter=0 return wapper @my_counter def minus(x,y): print('Cals: %s-%s=' %(x,y),end='') return x-y print(minus(2,1),' counter:',minus.counter) print(minus(2,1),' counter:',minus.counter) print(minus(2,1),' counter:',minus.counter) @my_counter def add(x,y): print('Cala: %s +%s='%(x,y),end='') return x + y print(add(1,2),' counter:',add.counter) print(add(1,2),' counter:',add.counter) print(add(1,2),' counter:',add.counter)
描述器
将类属性作为对象,管理一个类属性的“访问”,“修改”,“删除”
class MyAttribute: def __get__(self, instance, owner): print('get:',self,instance,owner) #instance是实例,owner是类 def __set__(self, instance, value): print('set:',self,instance,value) #value 是赋的值 def __delete__(self, instance): print('delete:',self,instance) class Myclass: attr=MyAttribute() mc=Myclass() print('xx') mc.attr mc.attr=1 del mc.attr 运行结构: xx get: <__main__.MyAttribute object at 0x10402ed30> <__main__.Myclass object at 0x10402eeb8> <class '__main__.Myclass'> set: <__main__.MyAttribute object at 0x10402ed30> <__main__.Myclass object at 0x10402eeb8> 1 delete: <__main__.MyAttribute object at 0x10402ed30> <__main__.Myclass object at 0x10402eeb8>
一个基于描述器的装饰器:
class Property(object): def __init__(self,fget=None): self.fget=fget def __get__(self, obj,objtype=None): if obj is None: return self if self.fget is None: raise AttributeError("unreadable attribute") return self.fget(obj) class Person(): def __init__(self,name): self._name=name self.is_anonymous=False @Property def name(self): if not self.is_anonymous: return self._name else: return 'anonymous' p=Person('Tuple') print(p.name) p.is_anonymous=True print(p.name)
常用的内置装饰器(property):就是把一个方法变成属性的样子
class Person: def __init__(self,name): self._name=name @property def name(self): print("通过property来获取name") if hasattr(self,'_name'): return self._name else: raise AttributeError('没有name这个属性') @name.setter def name(self,value): print('通过property来设置name') self._name=value @name.deleter def name(self): print('通过propety来删除name') del self._name