Part of Knowledge Points of Python Object-Oriented Programming Day 28

Keywords: Python Attribute Programming network

_ enter_ and exit__

 with obj as f:

'Code Block'

1. With obj - > Trigger obj. _enter_() to get the return value

2. as F - > F = return value

3.with obj as f equals f = obj. _enter_()

4. Execution code block

In two cases:

In the absence of exceptions, the entire block of code runs and triggers _exit_ with three parameters of None

In the case of anomaly, the _exit_ will be triggered directly from the position where the anomaly occurs, which can be divided into two cases:

If the return value of _exit_ is True, the exception is swallowed.

If the return value of _exit_ is not True, the exception is vomited

(exit means that the whole with statement is executed, and the statement in the code block will not execute after the exception.)

 

Purpose: The purpose of using with statements is to avoid manual cleaning. In addition, in programming environments where some resources such as files, network connections and locks need to be managed, the mechanism of automatically releasing resources can be customized in _exit_.

 

A Simple Understanding of Anomaly Composition

Exception classes, outliers, and trace information correspond to exc_type/exc_val/exc_tb, respectively

 

Descriptor application

 1 class Typed:
 2     def __init__(self,key,expected_type):
 3         self.key=key
 4         self.expected_type=expected_type
 5     def __get__(self, instance, owner): #instance yes p1 Example
 6         print('get Method')
 7         return instance.__dict__[self.key]
 8     def __set__(self, instance, value):
 9         print('set Method')
10         if not isinstance(value,self.expected_type):
11             raise TypeError('%s The type of incoming is not%s' %(self.key,self.expected_type))
12         instance.__dict__[self.key]=value
13     def __delete__(self, instance):
14         print('delete Method')
15         instance.__dict__.pop(self.key)
16 
17 class People:
18     name=Typed('name',str) #t1.__set__()  self.__set__()
19     age=Typed('age',int) #t1.__set__()  self.__set__()
20     def __init__(self,name,age,salary):
21         self.name=name
22         self.age=age
23         self.salary=salary
24 
25 p1=People(213,13,13.3)

output

Traceback (most recent call last):
File "G:/Baidu NetdiskDownload/Phase 04-Python 3 Object-Oriented Programming (24-28)/Pthon Full Stack S3 day028/day28 Class Code/Descriptor Application.py", line 41, in <module>
p1=People(213,13,13.3)
File "G:/Baidu NetdiskDownload/Phase 04-Python 3 Object-Oriented Programming (24-28)/Pthon Full Stack S3 day028/day28 Class Code/Descriptor Application.py", line 36, in__init__
self.name=name
File "G:/Baidu NetdiskDownload/Phase 04-Python 3 Object-Oriented Programming (24-28)/Pthon Full Stack S3 day028/day28 Class Code/Descriptor Application.py", line 25, in _set__
raise TypeError('%s incoming type is not% s'% (self. key, self. expected_type))
TypeError: The type of name input is not <class'str'>

 

Class Decorator

 

 1 def deco(obj):
 2     print('==========',obj)
 3     obj.x=1
 4     obj.y=2
 5     obj.z=3
 6     return obj
 7 
 8 @deco #Foo=deco(Foo)
 9 class Foo:
10     pass
11 
12 print(Foo.__dict__)

output

========== <class '__main__.Foo'>
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}

 

 

Implementing Delay Computing Function with Self-customized property

 1 class Lazyproperty:
 2     def __init__(self,func):
 3         # print('==========>',func)
 4         self.func=func
 5     def __get__(self, instance, owner):
 6         print('get')
 7         if instance is None:
 8             return self
 9         res=self.func(instance) #Functions run by passing in instances themselves, not classes
10         setattr(instance,self.func.__name__,res)
11         return res
12     # def __set__(self, instance, value):  
13     #     pass
14 
15 class Room:
16     def __init__(self,name,width,length):
17         self.name=name
18         self.width=width
19         self.length=length
20     @Lazyproperty  # area=Lazypropery(area)
21     def area(self):
22         return self.width * self.length
23     @property  # area1=property(area1)
24     def area1(self):
25         return  self.width * self.length
26 
27 r1=Room('Toilet',1,1)
28 print(r1.__dict__)
29 
30 # Instance call
31 print(r1.area)
32 print(r1.__dict__)
33 print(Room.__dict__)
34 
35 # Class invokes the attribute instance of the descriptor proxy and passes None owner unchanged
36 print(Room.area)
37 
38 # The get method is no longer called because there are instance attributes.
39 # Its priority is higher than that of non-data descriptors. If set attribute is added at this time, it can not be realized.
40 print(r1.area)
41 print(r1.area)

Output

{name':'toilet','width': 1,'length': 1}
get
1
{name':'toilet','width': 1,'length': 1,'area': 1}
{'__module__': '__main__', '__init__': <function Room.__init__ at 0x000001EFB23EA620>, 'area': <__main__.Lazyproperty object at 0x000001EFB07D8908>, 'area1': <property object at 0x000001EFB0799688>, '__dict__': <attribute '__dict__' of 'Room' objects>, '__weakref__': <attribute '__weakref__' of 'Room' objects>, '__doc__': None}
get
<__main__.Lazyproperty object at 0x000001EFB07D8908>
1
1

 

property Supplement

 1 class Foo:
 2     @property
 3     def AAA(self):
 4         print('get Run me when it's time.')
 5 
 6     # The following two functions depend on the existence of static attributes
 7     @AAA.setter
 8     def AAA(self,val):
 9         print('set Run me when it's time.',val)
10     @AAA.deleter
11     def AAA(self):
12         print('del Run me when it's time.')
13 #Only in attributes AAA Definition property Only then can it be defined AAA.setter,AAA.deleter
14 f1=Foo()
15 f1.AAA
16 f1.AAA='aaa'
17 del f1.AAA

#Another way of writing, the effect is the same.
class Foo:

def get_AAA(self):
print('get Run me when it's time.')
def set_AAA(self,val):
print('set Run me when it's time.',val)
def del_AAA(self):
print('del Run me when it's time.')

AAA=property(get_AAA,set_AAA,del_AAA)  #Don't change the order.
f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA
 

output

Run me when get
Run me aaa when set
Run me when del

 

Meta class

The type metaclass is the class of the class and the template of the class. 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.

1 def say_hi(name):
2     return('hello,%s'%name)
3 FFo=type('FFo',(object,),{'gender':'female','say_hi':say_hi})
4 print(FFo)
5 print(FFo.__dict__)
6 print(FFo.say_hi('chenyuan'))
7 print('Your gender is %s'%FFo.gender)

output

<class '__main__.FFo'>
{'gender': 'female', 'say_hi': <function say_hi at 0x000001CF9911C1E0>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'FFo' objects>, '__weakref__': <attribute '__weakref__' of 'FFo' objects>, '__doc__': None}
hello,chenyuan
Your gender is female

When an instance calls a function, it automatically passes in the instance itself as a parameter, while when a class calls a function, it writes self if necessary.

 

Self-customized metaclass

 1 class MyType(type):
 2     def __init__(self,a,b,c):
 3         print('Construction function execution of metaclass')
 4         # print(a)
 5         # print(b)
 6         # print(c)
 7     def __call__(self, *args, **kwargs):
 8         # print('=-======>')
 9         # print(self)
10         # print(args,kwargs)
11         obj=object.__new__(self) #object.__new__(Foo)-->f1
12         self.__init__(obj,*args,**kwargs)  #Foo.__init__(f1,*arg,**kwargs)
13         return obj
14 class Foo(metaclass=MyType): #Foo=MyType(Foo,'Foo',(),{})--->__init__
15     def __init__(self,name):
16         self.name=name #f1.name=name
17 # print(Foo)
18 # f1=Foo('alex')
19 # print(f1)
20 
21 f1=Foo('alex')
22 print(f1)
23 print(f1.__dict__)

output

Construction function execution of metaclass
<__main__.Foo object at 0x0000025A13005048>
{'name': 'alex'}

Posted by u01jmg3 on Mon, 06 May 2019 01:45:38 -0700