# Descriptor application 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 passed in type is not %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)
# Class decorator def deco(obj): obj.a = 2 obj.b = 20 return obj @deco # Aoo = deco(Aoo) class Aoo: pass Aoo() print(Aoo.__dict__)
# Class decorator revision 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 decorator application 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 passed in type is not %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__ The context management protocol, the with statement, in order to make an object compatible with the with statement, the __enter_ and __exit__ methods must be declared in the object's class class Open: def __init__(self,name): self.name=name def __enter__(self): print("With statement, the __enter__ of the object is triggered, and the return value is assigned to the variable declared by r") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("Execute me when the code block in with is executed") with Open("a.txt")as r: print("sb") print("2222222")
The three parameters in __exit__() represent the exception type, Abnormal value and traceability information. If the code in the with statement is abnormal, the code after the with cannot be executed class Open: def __init__(self,name): self.name=name def __enter__(self): print("With statement, the __enter__ of the object is triggered, and the return value is assigned to the variable declared by r") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("Execute me when the code block in with is executed") with Open("a.txt")as r: print("sb") print(ssdasdad) print("111111111111111") print("2222222")
If the return value of __exit__() is True, then abnormal Will be emptied, as if nothing happened, the statement after with is executed normally class Open: def __init__(self,name): self.name=name def __enter__(self): print("With statement, the __enter__ of the object is triggered, and the return value is assigned to the variable declared by r") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("Execute me when the code block in with is executed") return True with Open("a.txt")as r: print("sb") print(ssdasdad) print("111111111111111") print("2222222")
1. Introduction class Aoo: pass r = Aoo() # r is an object instantiated by the Aoo class Everything in python is an object, and the class itself is also an object. When the keyword class is used, the python parser will create an object when loading the class (the object here refers to the class rather than the instance of the class) In the above example, we can see that r is an object produced by the class Aoo, and Aoo itself is also an object. Then which class is produced by it? The type function can be used to view the type, and can also be used to view the class of the object, both are the same print(type(r)) # Output:means that the obj object is created by the Aoo class print(type(Aoo)) # Output: 2. What is a metaclass Metaclass is the class of the class, the template of the class Metaclasses are used to control how to create classes, just as classes are templates for creating objects A metaclass is an instance as a class, just as an instance of a class is an object (the r object is an instance of Aoo, and the Aoo class is an instance of the type class) type is a built-in metaclass of python, which is used to directly control the generated class. Any class defined by a class in python is actually an object instantiated by the typr class 3. Two ways to create metaclasses The first: class Aoo: def __init__(self): pass The second type: def __init__(self,name,age): self,name = name self.age = age Aoo = type("Aoo",(object,),{"x":1,"__init__":__init__}) 4. A class does not declare its own metaclass. By default, its metaclass is type. In addition to using the metaclass type, users can also customize the metaclass by inheriting 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 # return 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)
Using the descriptor to customize the 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, the result of running 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("unknown",2,20) # Instance call print(r.area) # Class call print(Aoo.area)
property supplement # AAA.setter, AAA.deleter can only be defined after the property AAA defines the property class Aoo: @property def AAA(self): print("Run me when get") @AAA.setter def AAA(self,val): print("Run me when set") @AAA.deleter def AAA(self): print("Run me when deleter") r = Aoo() r.AAA r.AAA = "aaa" del r.AAA class Aoo: def get_AAA(self): print("Run me when get") def set_AAA(self,val): print("Run me when set") def del_AAA(slef): print("Run me when deleter") AAA = property(get_AAA,set_AAA,del_AAA) r = Aoo() r.AAA r.AAA = "aaa" del r.AAA
property usage class Aoo: def __init__(self): # Original price self.original_price = 100 # Discount self.discount = 0.8 @property def price(self): # Actual price = original price * discount 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) # Get product price a.price = 200 # Modify the original price of the product print(a.price) del a.price # Delete the original price of the product # print(a.price)
# Descriptor application 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 passed in type is not %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)
# Class decorator def deco(obj): obj.a = 2 obj.b = 20 return obj @deco # Aoo = deco(Aoo) class Aoo: pass Aoo() print(Aoo.__dict__)
# Class decorator revision 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 decorator application 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 passed in type is not %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__ The context management protocol, the with statement, in order to make an object compatible with the with statement, the __enter_ and __exit__ methods must be declared in the object's class class Open: def __init__(self,name): self.name=name def __enter__(self): print("With statement, the __enter__ of the object is triggered, and the return value is assigned to the variable declared by r") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("Execute me when the code block in with is executed") with Open("a.txt")as r: print("sb") print("2222222")
The three parameters in __exit__() represent the abnormal type, abnormal value and traceability information, and the code in the with statement is abnormal Then the code after with cannot be executed class Open: def __init__(self,name): self.name=name def __enter__(self): print("With statement, the __enter__ of the object is triggered, and the return value is assigned to the variable declared by r") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("Execute me when the code block in with is executed") with Open("a.txt")as r: print("sb") print(ssdasdad) print("111111111111111") print("2222222")
If the return value of __exit__() is True, the exception will be cleared, as if nothing happened. The statement after with is executed normally class Open: def __init__(self,name): self.name=name def __enter__(self): print("With statement, the __enter__ of the object is triggered, and the return value is assigned to the variable declared by r") #return self def __exit__(self,exc_type,exc_val,exc_tb): print("Execute me when the code block in with is executed") return True with Open("a.txt")as r: print("sb") print(ssdasdad) print("111111111111111") print("2222222")
1, introduction class Aoo: pass r = Aoo() # r is an object instantiated by the Aoo class Everything in python is an object, and the class itself is also an object. When the keyword class is used, the python parser will create an object when loading the class (the object here refers to the class rather than the instance of the class) In the above example, we can see that r is an object produced by the class Aoo, and Aoo itself is also an object. Then which class is produced by it? The type function can be used to view the type, and can also be used to view the class of the object, both are the same print(type(r)) # Output:means that the obj object is created by the Aoo class print(type(Aoo)) # Output: 2. What is a metaclass Metaclass is the class of the class, the template of the class Metaclasses are used to control how to create classes, just as classes are templates for creating objects A metaclass is an instance as a class, just as an instance of a class is an object (the r object is an instance of Aoo, and the Aoo class is an instance of the type class) type is a built-in metaclass of python, which is used to directly control the generated class. Any class defined by a class in python is actually an object instantiated by the typr class 3. Two ways to create metaclasses The first: class Aoo: def __init__(self): pass The second type: def __init__(self,name,age): self,name = name self.age = age Aoo = type("Aoo",(object,),{"x":1,"__init__":__init__}) 4. A class does not declare its own metaclass. By default, its metaclass is type. In addition to using the metaclass type, users can also customize the metaclass by inheriting 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 # return 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)
Using the descriptor to customize the 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, the result of running 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("unknown",2,20) # Instance call print(r.area) # Class call print(Aoo.area)
property supplement # AAA.setter, AAA.deleter can only be defined after the property AAA defines the property class Aoo: @property def AAA(self): print("Run me when get") @AAA.setter def AAA(self,val): print("Run me when set") @AAA.deleter def AAA(self): print("Run me when deleter") r = Aoo() r.AAA r.AAA = "aaa" del r.AAA class Aoo: def get_AAA(self): print("Run me when get") def set_AAA(self,val): print("Run me when set") def del_AAA(slef): print("Run me when deleter") AAA = property(get_AAA,set_AAA,del_AAA) r = Aoo() r.AAA r.AAA = "aaa" del r.AAA
property usage class Aoo: def __init__(self): # Original price self.original_price = 100 # Discount self.discount = 0.8 @property def price(self): # Actual price = original price * discount 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) # Get product price a.price = 200 # Modify the original price of the product print(a.price) del a.price # Delete the original price of the product # print(a.price)