# 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)