实现给类添加属性
def Typed(**kwargs):
def deco(obj):
for key,val in kwargs.items():
# obj.key = val
setattr(obj,key,val)
return obj
print('==>',kwargs)
return deco
@Typed(x=1,y=2,z=3)
class Foo:
pass
# f = Foo()
print(Foo.__dict__) #给Foo类添加属性成功
#{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}
@Typed(name='ago')
class Bar:
pass
print(Bar.__dict__)
'''
==> {'x': 1, 'y': 2, 'z': 3}
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}
==> {'name': 'ago'}
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Bar' objects>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None, 'name': 'ago'}
'''
实现输入的类型判断
class Typed:
def __init__(self,key,expected_type):
self.key=key
self.expected_type=expected_type
def __get__(self, instance, owner):
print('get方法')
return instance.__dict__[self.key]
def __set__(self, instance, value):
print('set方法')
if not isinstance(value,self.expected_type):
raise TypeError('%s 传入的类型不是%s' %(self.key,self.expected_type))
instance.__dict__[self.key]=value
def __delete__(self, instance):
print('delete方法')
instance.__dict__.pop(self.key)
def deco(**kwargs): #kwargs={'name':str,'age':int}
def wrapper(obj): #obj=People
for key,val in kwargs.items():#(('name',str),('age',int))
setattr(obj,key,Typed(key,val))
return obj
return wrapper
@deco(name=str,age=int) #@wrapper ===>People=wrapper(People)
class People:
name='alex'
def __init__(self,name,age,salary,gender,heigth):
self.name=name
self.age=age
self.salary=salary
print(People.__dict__)
p = People('tiger',12,221,'nan','21')
'''
{'__module__': '__main__', 'name': <__main__.Typed object at 0x0000024B9C5B86A0>, '__init__': <function People.__init__ at 0x0000024B9C44CB70>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'age': <__main__.Typed object at 0x0000024B9C5B8710>}
set方法
set方法
'''
通过描述符实现property功能
class Lazyproperty:
def __init__(self,func):
self.func = func
# print("xxx")
def __get__(self, instance, owner): #不设置__set__函数,非数据描述符才能够实现缓存效果
# print(instance)
# print(owner)
if instance == None: #类自己调用
return self.func
else:
res = self.func(instance)
print('get exec')
setattr(instance,self.func.__name__,res) #将area的值设置成为area函数的属性
return res
class Room:
def __init__(self,length,width):
self.length = length
self.width = width
# @property
@Lazyproperty
def area(self):
return self.length * self.width
r1 = Room(2,12)
print(r1.area)
print(Room.area)
'''
get exec
24
<function Room.area at 0x000001FA68F86C80>
'''