day28-python之property
1.property用法
# class Goods: # def __init__(self): # # 原价 # self.original_price = 100 # # 折扣 # self.discount = 0.8 # # @property # def price(self): # # 实际价格 = 原价 * 折扣 # new_price = self.original_price * self.discount # return new_price # # @price.setter # def price(self, value): # self.original_price = value # # @price.deleter # def price(self): # del self.original_price class Goods: def __init__(self): self.original_price = 100 self.discount = 0.8 @property def price(self): new_price = self.original_price * self.discount return new_price @price.setter def price(self,value): self.original_price = value @price.deleter def price(self): del self.original_price obj = Goods() print(obj.price) obj.price = 200 print(obj.price) del obj.price print(obj.price) # obj = Goods() # print(obj.price) # 获取商品价格 # obj.price = 200 # 修改商品原价 # print(obj.price) # del obj.price # 删除商品原价 # print(obj.price)
2.property补充
# class Foo: # @property # def AAA(self): # print('get的时候运行我啊') # # @AAA.setter # def AAA(self,val): # print('set的时候运行我啊',val) # @AAA.deleter # def AAA(self): # print('del的时候运行我啊') # #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter # f1=Foo() # f1.AAA # f1.AAA='aaa' # del f1.AAA # class Foo: # # def get_AAA(self): # print('get的时候运行我啊') # def set_AAA(self,val): # print('set的时候运行我啊',val) # def del_AAA(self): # print('del的时候运行我啊') # # AAA=property(get_AAA,set_AAA,del_AAA) # #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter # f1=Foo() # f1.AAA # f1.AAA='aaa' # del f1.AAA
3.上下文管理协议
# class Foo: # def __init__(self,name): # self.name=name # # def __enter__(self): # print('执行enter') # return self # # def __exit__(self, exc_type, exc_val, exc_tb): # print('执行exit') # print(exc_type) # print(exc_val) # print(exc_tb) # return True # with Foo('a.txt') as f: # print(f) # print(asdfsaasdfasdfasdfasdfasfasdfasdfasdfasdfasfdasfd) #触发__exit__ # print(f.name) # print('-----------------') # print('-----------------') # print('-----------------') # print('-----------------') # print('-----------------') # print('-----------------') # print('-----------------') # print('000000000000000000000000000000000000000000000')
with obj as f:
'代码块'
1.with obj ----》触发obj.__enter__(),拿到返回值
2.as f----->f=返回值、
3.with obj as f 等同于 f=obj.__enter__()
4.执行代码块
一:没有异常的情况下,整个代码块运行完毕后去触发__exit__,它的三个参数都为None
二:有异常的情况下,从异常出现的位置直接触发__exit__
a:如果__exit__的返回值为True,代表吞掉了异常
b:如果__exit__的返回值不为True,代表吐出了异常
c:__exit__的的运行完毕就代表了整个with语句的执行完毕
#自省
hasattr(obj,'属性') #obj.属性 是否存在
getattr(obj,'属性') #获取obj.属性 不存在则报错
getattr(obj,'属性','默认值') #获取obj.属性 不存在不会报错,返回那个默认值
setattr(obj,'属性','属性的值') #obj.属性=属性的值
delattr(obj,'属性') #del obj.属性
#__getattr__,__setattr__,__delattr__
obj点的方式去操作属性时触发的方法
__getattr__:obj.属性 不存在时触发
__setattr__:obj.属性=属性的值 时触发
__delattr__:del obj.属性 时触发
#__getitem__,__setitem_,__delitem__
obj[‘属性’]的方式去操作属性时触发的方法
__getitem__:obj['属性'] 时触发
__setitem__:obj['属性']=属性的值 时触发
__delitem__:del obj['属性'] 时触发
#__get__,__set__,__delete__
描述就是一个新式类,这个类至少要实现上述三个方法的一个
class 描述符:
def __get__():
pass
def __set__():
pass
def __delete__():
pass
class 类:
name=描述符()
obj=类()
obj.name #get
obj.name='egon' #set
del obj.name #delete
#__del__:析构方法
垃圾回收时触发
4.元类介绍
# class Foo: # pass # # f1=Foo() #f1是通过Foo类实例化的对象 # # print(type(f1)) # print(type(Foo)) # # class Bar: # pass # # print(type(Bar)) # class Foo: # def __init__(self): # pass # print(Foo) # print(Foo.__dict__) # # def __init__(self,name,age): # self.name=name # self.age=age # def test(self): # print('=====>') # FFo=type('FFo',(object,),{'x':1,'__init__':__init__,'test':test}) # print(FFo) # print(FFo.__dict__) # # f1=FFo('alex',18) # print(f1.name) # f1.test()
5.利用描述符自定制property
# class Lazyproperty: # def __init__(self,func): # # print('==========>',func) # self.func=func # def __get__(self, instance, owner): # print('get') # # print(instance) # # print(owner) # if instance is None: # return self # res=self.func(instance) # setattr(instance,self.func.__name__,res) # return res # def __set__(self, instance, value): # pass class Lazypropery: def __init__(self,func): self.func = func def __get__(self, instance, owner): print('get') if instance is None: return self res = self.func(instance) setattr(instance,self.func.__name__,res) return res def __set__(self, instance, value): pass class Room: def __init__(self,name,width,length): self.name = name self.width = width self.length = length @Lazypropery def area(self): return self.width*self.length @property def areal(self): return self.width*self.length print(Room.__dict__) r1 = Room('厕所',1,1) print(r1.__dict__) # class Room: # def __init__(self,name,width,length): # self.name=name # self.width=width # self.length=length # # @property #area=property(area) # @Lazyproperty #area=Lazypropery(area) # def area(self): # return self.width * self.length # @property #test=property(test) # def area1(self): # return self.width * self.length # # print(Room.__dict__) # r1=Room('厕所',1,1) # print(r1.__dict__) print(r1.area) print(Room.__dict__) #实例调用 # print(r1.area) # print(Room.__dict__) #类调用 # print(Room.area) print(Room.area) print(r1.test) print(Room.test) # print(r1.test) # print(Room.test) # print(r1.area1) # print(r1.area1) # print(r1.area1) # print(r1.area1) print(r1.areal) print(r1.areal) print(r1.areal) print(r1.areal) print(r1.areal) print(r1.areal) # print(r1.area) # print(r1.__dict__) # # print(r1.area) # print(r1.area) # print(r1.area) # print(r1.area) # print(r1.area) # print(r1.area) # print(r1.area) # print(r1.area)
6.类的装饰器
# def deco(func): # print('==========') # return func # # # @deco #test=deco(test) # # def test(): # # print('test函数运行') # # test() # # @deco #Foo=deco(Foo) # class Foo: # pass # def deco(obj): # print('==========',obj) # 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__)
7.装饰器修订版
# def Typed(**kwargs): # def deco(obj): # for key,val in kwargs.items(): # # obj.key=val # setattr(obj,key,val) # return obj # return deco def Typed(**kwargs): def deco(obj): for key,val in kwargs.items(): setattr(obj,key,val) return obj return deco @Typed(x=1,y=2,z=3) class Foo: pass print(Foo.__dict__) @Typed(name='egon') class Bar: pass print(Bar.name) # @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)
8.类的装饰器的应用
# 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) # # 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) 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): def wrapper(obj): for key,val in kwargs.items(): setattr(obj,key,Typed(key,val)) return obj return wrapper @deco(name=str,age=int) class People: name = 'alex' def __init__(self,name,age,salary,gender,heigth): self.name = name self.age = age self.salary = salary print(People.__dict__) # 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)) # # setattr(People,'name',Typed('name',str)) #People.name=Typed('name',str) # return obj # return wrapper # @deco(name=str,age=int) #@wrapper ===>People=wrapper(People) # class People: # name='alex' # # name=Typed('name',str) # # age=Typed('age',int) # def __init__(self,name,age,salary,gender,heigth): # self.name=name # self.age=age # self.salary=salary # # p1=People('213',13.3,13.3,'x','y') # print(People.__dict__)
9.自定制classmethod
# class ClassMethod: # def __init__(self,func): # self.func=func # def __get__(self, instance, owner): #类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身, # def feedback(*args,**kwargs): # print('在这里可以加功能啊...') # return self.func(owner,*args,**kwargs) # return feedback class ClassMethod: def __init__(self,func): self.func = func def __get__(self, instance, owner): def feedback(*args,**kwargs): print('在这里可以加功能啊...') return self.func(owner,*args,**kwargs) return feedback class People: name = 'linhaifeng' @ClassMethod def say_hi(cls,msg,x): print('你好啊,帅哥%s%s%s'%(cls,msg,x)) # People.say_hi('你那是偷心的贼',10) # class People: # name='linhaifeng' # @ClassMethod # say_hi=ClassMethod(say_hi) # def say_hi(cls,msg,x): # print('你好啊,帅哥 %s %s %s' %(cls.name,msg,x)) # # People.say_hi('你是那偷心的贼',10) # # p1=People() # p1.say_hi('你是那偷心的贼',10) p1 = People() p1.say_hi('你那是',11)
10.自定义制元类
# class MyType(type): # def __init__(self,a,b,c): # print('元类的构造函数执行') # # print(a) # # print(b) # # print(c) # def __call__(self, *args, **kwargs): # # print('=-======>') # # print(self) # # print(args,kwargs) # obj=object.__new__(self) #object.__new__(Foo)-->f1 # self.__init__(obj,*args,**kwargs) #Foo.__init__(f1,*arg,**kwargs) # return obj # class Foo(metaclass=MyType): #Foo=MyType(Foo,'Foo',(),{})---》__init__ # def __init__(self,name): # self.name=name #f1.name=name class MyType(type): def __init__(self,a,b,c): print('元类的构造函数执行') def __call__(self, *args, **kwargs): obj = object.__new__(self) self.__init__(obj,*args,**kwargs) return obj class Foo(metaclass=MyType): def __init__(self,name): self.name = name # print(Foo) # f1 = Foo('alex') # print(f1) f1 = Foo('alex') print(f1) print(f1.__dict__) # print(Foo) # f1=Foo('alex') # print(f1) # f1=Foo('alex') # print(f1) # print(f1.__dict__)
11.自定义制元类精简版
# class MyType(type): # def __init__(self,a,b,c): # print('元类的构造函数执行') # def __call__(self, *args, **kwargs): # obj=object.__new__(self) # self.__init__(obj,*args,**kwargs) # return obj # class Foo(metaclass=MyType): # def __init__(self,name): # self.name=name # f1=Foo('alex') class MyType(type): def __init__(self,a,b,c): print('元类的构造函数执行') def __call__(self, *args, **kwargs): obj = object.__new__(self) self.__init__(obj,*args,**kwargs) return obj class Foo(metaclass=MyType): def __init__(self,name): self.name = name f1 = Foo('alex')