1 class property2: 2 def __init__(self, func): 3 print('执行property2') 4 self.func = func 5 6 def __get__(self, instance, owner): 7 print('执行get') 8 setattr(instance, self.func.__name__, self.func(instance)) 9 return self.func(instance) 10 11 def __set__(self, instance, value): # 加上set方法就变成数据描述符,优先级变高。导致每次执行 12 print('set') 13 14 15 class Room: 16 def __init__(self, name, width, length): 17 self.name = name 18 self.width = width 19 self.length = length 20 21 @property2 # area = property2(area) 22 def area(self): 23 return self.width * self.length 24 25 26 r1 = Room('cesuo', 100, 20) 27 print(r1.area) # 如果是非数据描述符那就是先从实例属性中去找。 28 print(r1.area) # 如果是数据描述符那就从先从类属性中找,然后从数据描述符中找。 29 print(r1.area) 30 print(r1.area) 31 print(r1.__dict__) 32 输出: 33 执行property2 34 执行get 35 set 36 2000 37 执行get 38 set 39 2000 40 执行get 41 set 42 2000 43 执行get 44 set 45 2000 46 {'name': 'cesuo', 'width': 100, 'length': 20}
非数据描述符就比实例属性优先级更低,从而不用每次都去执行描述符。而是先从实例属性字典去中找
下面的为自定义类方法:
1 class ClassMethod: 2 def __init__(self, func): 3 self.func = func 4 5 def __get__(self, instance, owner): 6 def wrapper(*args,**kwargs): 7 print('123456789') 8 return self.func(owner,*args,**kwargs) 9 10 return wrapper 11 12 13 class Foo: 14 def __init__(self, name, age, gender): 15 self.name = name 16 self.age = age 17 self.gender = gender 18 19 @ClassMethod 20 def test(cls, name,age): 21 print('ok%s%s' % (name,age)) 22 23 24 Foo.test('nihao',132) 25 输出: 26 123456789 27 oknihao132
下面的为自定义静态方法:
1 class Method: 2 def __init__(self, func): 3 print('+++++++++++') 4 self.func = func 5 6 def __get__(self, instance, owner): 7 def wrapper(*args, **kwargs): 8 return self.func(*args, **kwargs) 9 10 return wrapper 11 12 13 class Foo: 14 def __init__(self, name, age): 15 self.name = name 16 self.age = age 17 18 @Method 19 def test(a, b, c): 20 print('ok%s%s%s' % (a, b, c)) 21 22 23 Foo.test(1,2,3) 24 f1 = Foo('alex',123) 25 f1.test(4,5,6) 26 输出: 27 +++++++++++ 28 ok123 29 ok456