# 描述符的应用class Aoo: def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __get__(self,instance,owner): return instance.__dict__[self.key] def __set__(self,instance,value): if not isinstance(
# 描述符的应用 class Aoo: def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __get__(self,instance,owner): return instance.__dict__[self.key] def __set__(self,instance,value): 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): instance.__dict__pop(self.key) class Foo: name = Aoo("name",str) age = Aoo("age",int) def __init__(self,name,age): self.name = name self.age = age r = Foo("lwj",18) print(r.name) print(r.age)
# 类的装饰器 def deco(obj): obj.a = 2 obj.b = 20 return obj @deco # Aoo = deco(Aoo) class Aoo: pass Aoo() print(Aoo.__dict__)
# 类的装饰器修订 def pice(**kwargs): def deco(obj): for key,values in kwargs.items(): setattr(obj,key,values) return obj return deco @pice(a=2,x=20) # deco = pice(a=2,x=20) Aoo= deco(Aoo) class Aoo: pass Aoo() print(Aoo.__dict__)
# 类的装饰器应用 class Aoo: def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __get__(self,instance,owner): return instance.__dict__[self.key] def __set__(self,instance,value): 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): instance.__dict__pop(self.key) def pice(**kwargs): # kwargs = {"name":str,"age":int} def deco(obj): # obj = Foo for key,values in kwargs.items(): # (("name",str),("age",int)) setattr(obj,key,Aoo(key,values)) # setattr(Foo,"name",Aoo("name",str)) return obj return deco @pice(name=str,age=int) # deco = pice(name=str,age=int) Foo = deco(Foo) class Foo: name = Aoo("name",str) age = Aoo("age",int) def __init__(self,name,age): self.name = name self.age = age r = Foo("lwj",18) print(r.__dict__)
__enter__ __exit__ 上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter_和__exit__方法 class Open: def __init__(self,name): self.name=name def __enter__(self): print("with语句,对象的__enter__被触发,有返回值则赋值给r声明的变量") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("with中代码块执行完毕时执行我") with Open("a.txt")as r: print("sb") print("2222222")
__exit__()中三个参数分别代表异常类型,异常值和追溯信息,with语句中代码出现异常则with后的代码都无法执行 class Open: def __init__(self,name): self.name=name def __enter__(self): print("with语句,对象的__enter__被触发,有返回值则赋值给r声明的变量") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("with中代码块执行完毕时执行我") with Open("a.txt")as r: print("sb") print(ssdasdad) print("111111111111111") print("2222222")
如果__exit__()返回值为True,那么异常会被清空,就好像什么都没发生一样,with后的语句正常执行 class Open: def __init__(self,name): self.name=name def __enter__(self): print("with语句,对象的__enter__被触发,有返回值则赋值给r声明的变量") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("with中代码块执行完毕时执行我") return True with Open("a.txt")as r: print("sb") print(ssdasdad) print("111111111111111") print("2222222")
1、引子 class Aoo: pass r = Aoo() # r 是通过Aoo类实例化的对象 python中一切皆对象,类本身也是一个对象,当使用关键字class的时候python解析器在加载class的时候就会创建一个对象(这里的对象指的是类而非类的实例) 上例可以看出r是由Aoo这个类产生的对象,而Aoo本身也是对象,那它又是由哪个类产生的呢? type函数可以查看类型,也可以用来查看对象的类,二者都是一样的 print(type(r)) # 输出:<class ‘__main__.Aoo‘> 表示,obj 对象由Aoo类创建 print(type(Aoo)) # 输出:<type ‘type‘> 2、什么是元类 元类是类的类,是类的模板 元类是用来控制如何创建类的,正如类是创建对象的模板一样 元类是实例为类,正如类的实例为对象(r对象是Aoo的一个实例,Aoo类是type类的一个实例) type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是typr类实例化的对象 3、创建元类的两种方法 第一种: class Aoo: def __init__(self): pass 第二种: def __init__(self,name,age): self,name = name self.age = age Aoo = type("Aoo",(object,),{"x":1,"__init__":__init__}) 4、一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承typr来自定义元类 class Mytepy(type): def __init__(self,a,b,c): pass def __class__(self,*args,**kwargs): obj = object.__new__(self) # obj = object.__new__(Aoo) self.__init__(obj,*args,**kwargs) # Aoo.__init__(r,*args,**kwargs) return obj # 返回 r class Aoo(metaclass=Mytepy): # Aoo = Mytepr("Aoo",(object,),{"name":name}) ---> __init__ def __init__(self,name): self.name = name r = Aoo("lwj") print(r.name)
利用描述符自定制property class Lazyproperty: def __init__(self,func): self.func = func def __get__(self,instance,owner): if instance is None: return self res = self.func(instance) # res = self.area(r) setattr(instance,self.func.__name__,res) # r,area,运行area的结果 return res class Aoo: def __init__(self,name,width,length): self.name = name self.width = width self.length = length @Lazyproperty # area = Lazypropery(area) def area(self): return self.width * self.length r = Aoo("未知",2,20) # 实例调用 print(r.area) # 类调用 print(Aoo.area)
property补充 # 只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter class Aoo: @property def AAA(self): print("get的时候运行我") @AAA.setter def AAA(self,val): print("set的时候运行我") @AAA.deleter def AAA(self): print("deleter的时候运行我") r = Aoo() r.AAA r.AAA = "aaa" del r.AAA class Aoo: def get_AAA(self): print("get的时候运行我") def set_AAA(self,val): print("set的时候运行我") def del_AAA(slef): print("deleter的时候运行我") AAA = property(get_AAA,set_AAA,del_AAA) r = Aoo() r.AAA r.AAA = "aaa" del r.AAA
property 用法 class Aoo: def __init__(self): # 原价 self.original_price = 100 # 折扣 self.discount = 0.8 @property def price(self): # 实际价格 = 原价 * 折扣 new_pirce = self.original_price * self.discount return new_pirce @price.setter def price(self,value): self.original_price = value @price.deleter def price(self): del self.original_price a = Aoo() print(a.price) # 获取商品价格 a.price = 200 # 修改商品原价 print(a.price) del a.price # 删除商品原价 # print(a.price)