类的装饰器基本原理
def deco(func):
print('==========')
return func
@deco #test=deco(test)
def test():
print('test函数运行')
test()
def deco(obj):
print('==========',obj) #obj是下面定义的Foo类
obj.x=1 #把类属性添加到底层字典当中
obj.y=2
obj.z=3
return obj 返回被装饰的类
@deco #Foo=deco(Foo)
class Foo:
pass
print(Foo.__dict__) #底层字典打印出上面设置的类属性值
一切皆对象
@deco #test=deco(test)
def test():
print('test函数')
test.x=1
test.y=1
print(test.__dict__)
类的装饰器加强版
def Typed(**kwargs): #在外面套一层函数,用于接收带参数的装饰器
def deco(obj):
for key,val in kwargs.items(): #循环参数的键值对
setattr(obj,key,val) #setattr方法设置Foo底层字典的键值对值
return obj #返回结果给Foo类
return deco #首先返回deco函数,此时装饰器前等于@deco---->Foo=deco(Foo)
@Typed(x=1,y=2,z=3) #1.Typed(x=1,y=2,z=3) --->deco 2.@deco---->Foo=deco(Foo)
class Foo:
pass
print(Foo.__dict__)
@Typed(name='egon') #@deco ---->Bar=deco(Bar)
class Bar:
pass
print(Bar.name)
对传入参数的类型进行判断
class Typed:
def __init__(self,key,expected_type):
self.key=key
self.expected_type=expected_type
def __get__(self, instance, owner):
print('get方法')
# print('instance参数【%s】' %instance) #instance参数是实例化出来的对象,owner是类本身
# print('owner参数【%s】' %owner)
return instance.__dict__[self.key] #返回从实例对象的底层字典中取出的值
def __set__(self, instance, value):
print('set方法')
# print('instance参数【%s】' % instance)
# print('value参数【%s】' % value)
# print('====>',self)
if not isinstance(value,self.expected_type):
# print('你传入的类型不是字符串,错误')
# return
raise TypeError('%s 传入的类型不是%s' %(self.key,self.expected_type))
instance.__dict__[self.key]=value
def __delete__(self, instance):
print('delete方法')
# print('instance参数【%s】' % instance)
instance.__dict__.pop(self.key)
def deco(**kwargs): #kwargs={'name':str,'age':int,'salary':float}
def wrapper(obj): #obj=People
for key,val in kwargs.items(): #(('name',str),('age',int))
setattr(obj,key,Typed(key,val)) #相等于people.name=Typed('name','str')
# setattr(People,'name',Typed('name',str)) #People.name=Typed('name',str)
return obj
return wrapper
设置传入字段类型限制
@deco(name=str,age=int,salary=float) #@wrapper ===>People=wrapper(People)
class People:
name=Typed('name',str) #相等于@deco(name=str)
age=Typed('age',int) #相等于@deco(age=int)
salary=Typed('salary',float)#相等于@deco(salary=float)
def __init__(self,name,age,salary,gender,height):
self.name=name
self.age=age
self.salary=salary
self.gender=gender
self.height=height
p1=People('213',13,13.3,'x','y')
print(p1.__dict__)
print(People.__dict__)