Python Object-Oriented Five Foundations

Python Object-Oriented Five Foundations

Today, we will learn the remaining object-oriented knowledge, mainly in the following aspects: 1. Context management protocol, 2. Decorating class 3. Metaclass

Context Management Protocol

When learning how to operate a file, the operation of a file is as follows:

with open('file name','Pattern')as f:
    'code block'

The above is called context management protocol, which is the with statement. In order to make an object compatible with the with statement, the _enter_ and _exit_ methods must be declared in the class of the object.

class Foo:
    def __init__(self,name):
        self.name=name

    def __enter__(self):
        print('implement enter')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('implement exit')
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return True


with Foo('a.txt') as f:  #f by Foo An instantiated object. f = Open('a.txt))
# implement with Foo('a.txt') as f It triggers Foo In the class__enter__Method This method self Pass it as a return value to f
#with When the code in the code block is executed, it triggers__exit__Method
    print(f)  #<__main__.Foo object at 0x01EC2070>
    print(asdfsaasdfasdfasdfasdfasfasdfasdfasdfasdfasfdasfd)  #Exceptions to code blocks
    # It will trigger directly.__exit__Method, the following code block will report an error, if in__exit__If there is a return value in the method, the error message will be swallowed up.
    print(f.name)
    print('-----------------')
    print('-----------------')
    print('-----------------')
    print('-----------------')
    print('-----------------')
    print('-----------------')
    print('-----------------')
print('000000000000000000000000000000000000000000000') #Execution first__exit__After the method, execute the sentence again

Uses or benefits:

1. The purpose of using with statements is to put code blocks into with and execute them. After with, the cleaning work is automatically completed without manual intervention.

2. In programming environments where resources such as files, network connections and locks need to be managed, you can customize the mechanism for automatically releasing resources in _exit_. You don't have to deal with this problem anymore. This will be very useful.

Loading decorators for classes

Ornaments have been learned when learning functions, and now they are still talking about ornaments when learning object-oriented. How do ornaments play in classes? First of all, we must have an understanding that: class and function are objects, so, let's look at the symbol of the decorator @, in a function or in a class or above the decorator is to express the above meaning?

# @Name————>The point is that it doesn't care what it's mounted on, it treats them as objects.
# eg:@echo  The execution of this sentence is equivalent to: teacher = echo(teacher)
#    def teacher()
#    @echo  The execution of this sentence is equivalent to: Student = echo(Student)
#    calss Student()

Let's start with an example of a function.

def decho(func):
    print('===========')
    return func

@decho   #Executing this trip is equivalent to==> test = decho(test)
def test():
    print('..............')

test()

//The results are as follows:
===========
..............

Another object-oriented example:

def test(obj):
    print('======>',obj)
    obj.name='alex'
    obj.age=45
    obj.gender='male'
    return obj
@test   # Equivalent to execution Foo = test(Foo)
class Foo():
    pass

print(Foo.__dict__)
print(Foo.name)

//The output is as follows:
======> <class '__main__.Foo'>
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'name': 'alex', 'age': 45, 'gender': 'male'}
alex

Finally, an example of an ornament with parameters is given.

def MO(**kwargs):
    def test(obj):
        print('---->',obj)
        for k ,v in kwargs.items():
            setattr(obj,k,v)
        return obj
    print('==================>',kwargs) #==================> {'name': 'alex', 'age': 45, 'gender': 'male'}
    return test

@MO(name='alex',age=45,gender='male')
class Teacher():
    print('___>')
    pass

print(Teacher.__dict__)

@MO(name='houliangong')
class Studet():
    print('wangbadan')

print(Studet.__dict__)


//The output is as follows:
==================> {'name': 'alex', 'age': 45, 'gender': 'male'}
___>
----> <class '__main__.Teacher'>
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Teacher' objects>, '__weakref__': <attribute '__weakref__' of 'Teacher' objects>, '__doc__': None, 'name': 'alex', 'age': 45, 'gender': 'male'}
==================> {'name': 'houliangong'}
wangbadan
----> <class '__main__.Studet'>
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Studet' objects>, '__weakref__': <attribute '__weakref__' of 'Studet' objects>, '__doc__': None, 'name': 'houliangong'}

3. Metaclass

What is metaclass? Metaclass means the class of a class. It's a template for creating a class. With it, you can create a class. so, do you have to learn how powerful it is?

Metaclasses are used to control how classes are created, just as classes are templates for creating objects

An instance of a metaclass is a class, just as an instance of a class is an object (f1 object is an instance of the Foo class and Foo class is an instance of the type class)

Type is a built-in metaclass of python that controls the generation of classes directly. Any class defined in Python is actually an object of type class instantiation

Two patterns for creating metaclasses:

Mode 1:

1 class Foo:
2     def func(self):
3         print('from func')

Mode 2:

1 def func(self):
2         print('from func')
3 x=1
4 Foo=type('Foo',(object,),{'func':func,'x':1})  #When creating a class, type needs to input three parameters: the first is the name of the class created, the second is the tuple of the class to which it belongs, and the third is the dictionary type of the incoming data attribute.

A class does not declare its own metaclass. By default, its metaclass is type. In addition to using metaclass type, users can also customize metaclass by inheriting type. (By the way, we can also see how metaclass controls class creation and what the workflow is.)

Okay, let's customize a metaclass:

class Mytype(type):
    def __init__(self,class_name,bases=None,dict=None):
        print("Mytype init--->")
        print(class_name,type(class_name))
        print(bases)
        print(dict)

    def __call__(self, *args, **kwargs):
        print('Mytype call---->',self,args,kwargs)
        obj=self.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj

class Foo(object,metaclass=Mytype):#in python3
    #__metaclass__ = MyType #in python2
    x=1111111111
    def __init__(self,name):
        self.name=name

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)
        # return object.__new__(cls) #Ditto


f1=Foo('name')
print(f1.__dict__)

That's all for today. I'm a little tired!

Keywords: Python Attribute Programming network

Added by x_maras on Wed, 03 Jul 2019 23:58:14 +0300