Object-oriented advanced 1

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

Leave a Comment

Your email address will not be published.