I, Isinstance (OBJ,CLS) and Issubclass (Sub,super)
Isinstance (obj,cls) checks if obj is an object of class CLS
Class Foo (object): pass obj = foo () isinstance (obj, foo)
Issubclass (sub, super) check if the sub class is a derived class of super class
Class Foo (object): Pass class Bar (foo): pass Issubclass (bar, foo)
Two-reflection
1 What is reflection
is the ability of a program to access, detect, and modify its own state or behavior (introspection)
2 Python Object-oriented reflection: manipulating object-related properties in the form of a string. All things in Python are objects (you can use reflection) three __setattr__,__delattr__,__getattr__
Class Foo: x=1 def __init__ (self,y): self.y=y def __getattr__ (self, item): print ('----> from GetAttr: The attribute you are looking for does not exist ') def __setattr__ (self, Key, value): print ('----> from setattr ') # self.key=value # This is infinite recursion, you think about it. self.__dict__[key]=value #应该使用它 def __delattr__ (self, item): print ('----> from Delattr ') # del Self.item #无限递归了 self.__dict__.pop (item) #__setattr__添加/Modify property will trigger its execution F1=foo (f1.__ DICT__) # because you rewrite the __setattr__, any assignment operation will trigger it to run, you do not write anything, is not assigned at all, unless you directly manipulate the property dictionary, otherwise you can never assign a value F1.z=3print (f1.__dict__) #__delattr_ _ f1.__dict__[' A ' is triggered when the property is deleted]=3# We can directly modify the property dictionary to complete the operation of adding/modifying Properties del f1.aprint (f1.__dict__) #__getattr__ The usage of f1.xxxxxx is triggered only when the attribute is called using the point and the property does not exist.
42 Secondary Processing standard type (packing)
Class List: #继承list所有的属性, you can also derive your own new, such as Append and mid def append (self, p_object): ' Derive your own append: plus type check ' if not isinstance (p_object,int): raise TypeError (' must be int ') super (). Append (p_object) @property def mid (self): ' Add your own property ' Index=len//2 return self[index]l=list ([1,2,3,4]) print (l) l.append (5) Print (L) # l.append (' 1111111 ') #报错, the Int type print (L.MID) must be #其余的方法都继承list的l. Insert (0,-123) print (L) l.clear () print (L) Two secondary processing standard type (based on inheritance implementation)
Five __getattribute__
Class Foo: def __init__ (self,x): self.x=x def __getattr__ (self, item): print (' Executed by Me ') # return Self.__dict__[item]f1=foo print (f1.x) f1.xxxxxx #不存在的属性访问, triggering __getattr__ review __getattr__
Class Foo: def __init__ (self,x): self.x=x def __getattribute__ (self, item): print (' I'll do it regardless of whether it exists) ' F1=foo (Ten) f1.xf1.xxxxxx__getattribute__
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' class Foo: def __init__ (self,x): self.x=x def __getattr__ ( Self, item): print (' Executed by Me ') # return Self.__dict__[item] def __getattribute__ (self, item): print (' Regardless of whether it exists, I will execute ') raise Attributeerror (' haha ') f1=foo () f1.xf1.xxxxxx# when __getattribute__ and __getattr__ exist at the same time, only execute __ getattrbute__, unless __getattribute__ throws an exception during execution Attributeerror both occur
Six descriptors (__get__,__set__,__delete__)
Descriptor is what: Descriptor is a new class, in this new class, at least the implementation of __get__ (), __set__ (), __delete__ (), which is also known as the Descriptor Protocol
__GET__ (): Triggers when a property is called
__set__ (): When assigning a value to a property, the trigger
__DELETE__ (): triggered when deleting an attribute with Del
Class Foo: #在python3中Foo是新式类, it implements three methods, this class is called a descriptor def __get__ (self, instance, owner): Pass def __set__ ( Self, instance, value): pass def __delete__ (self, Instance): Pass defines a descriptor
What is a 2 descriptor for: The function of the descriptor is to proxy the properties of another class (the descriptor must be defined as a class attribute of the class and cannot be defined in the constructor)
Class Foo: def __get__ (self, instance, owner): print (' Trigger get ') def __set__ (self, instance, value): Print (' trigger set ') def __delete__ (self, Instance): print (' trigger delete ') #包含这三个方法的新式类称为描述符, the invocation/assignment of the property by the instance generated by this class The deletion, and does not trigger these three methods F1=foo () f1.name= ' Egon ' F1.namedel f1.name# doubt: When, where, will trigger the execution of these three methods: the property operation of the instance generated by the descriptor class does not trigger the execution of three methods
#描述符Strclass Str: def __get__ (self, instance, owner): print (' Str call ') def __set__ (self, instance, value): print (' str settings ... ') def __delete__ (self, Instance): print (' str delete ... ') #描述符Intclass Int: def __get__ (self, instance, owner): print (' Int call ') def __set__ (self, instance, value): print (' int set ... ') def __delete__ (self, Instance): print (' int delete ... ') class people: name=str () Age=int () def __init__ (self,name,age): #name被Str类代理, age is represented by Int class, self.name=name self.age=age #何地? : A class attribute that is defined as another class # when? : And see the following demo p1=people (' Alex ') #描述符Str的使用p1. Namep1.name= ' Egon ' del p1.name# descriptor int using P1.agep1.age=18del p1.age# Let's just look at what happened. Print (p1.__dict__) print (people.__dict__) #补充print (Type (p1) = = people) #type (obj) is to see which class the obj is instantiated by, print (Type p1). __dict__ = = people.__dict__) When and where is the descriptor applied?
3 descriptors are divided into two types
A data descriptor: at least __get__ () and __set__ () are implemented
Class Foo: def __set__ (self, instance, value): print (' Set ') def __get__ (self, instance, owner): Print (' Get ')
Two non-data descriptors: no implementation __set__ ()
Class Foo: def __get__ (self, instance, owner): print (' Get ')
4 Precautions:
A descriptor itself should be defined as a new class, and the class being represented should also be a new class
The descriptor must be defined as a class property of this class and cannot be defined in a constructor
Three to strictly follow this priority, priority from high to the end is
1. Class Properties
2. Data descriptors
3. Instance Properties
4. Non-data descriptors
5. Property not found triggering __getattr__ ()
Six again See property
The nature of a static property is to implement the Get,set,delete three methods
Class Foo: @property def aaa (self): print ("Run me when get") @AAA. Setter def aaa (Self,value): print ("Run Me When set") @AAA. Deleter def AAA (self): print (' Run me when delete ') # Aaa.setter,aaa.deleterf1=foo () F1 can be defined only after the property AAA defines the properties. Aaaf1.aaa= ' AAA ' del F1. AAA Usage One
Class Foo: def get_aaa (self): print (' Run me when get ') def set_aaa (self,value): print (' Run me When set ') def delete_aaa (self): print (' Run me when delete ') Aaa=property (GET_AAA,SET_AAA,DELETE_AAA) # The built-in property has three parameters corresponding to the Get,set,delete one by one f1=foo () F1. Aaaf1.aaa= ' AAA ' del F1. AAA Usage II
Seven __setitem__,__getitem,__delitem__
Class Foo: def __init__ (self,name): self.name=name def __getitem__ (self, item): Print (self.__dict __[item]) def __setitem__ (self, Key, value): self.__dict__[key]=value def __delitem__ (self, key): print (' del Obj[key], I execute ') self.__dict__.pop (key) def __delattr__ (self, item): print (' Del Obj.key when I execute ') Self.__dict__.pop (item) f1=foo (' SB ') f1[' age ']=18f1[' age1 ']=19del f1.age1del f1[' "Age ']f1[' name ']= ' Alex ' Print (f1.__dict__)
Eight __str__,__repr__,__format__
Changing the object's string display __str__,__repr__
Self-Customizing formatted string __format__
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' format_dict={' nat ': ' {obj.name}-{obj.addr}-{obj.type} ', #学校名-school address-school type ' TNA ': ' {obj.type}:{obj.name}:{obj.addr} ', #学校类型: School Name: School address ' tan ': ' {obj.type}/{obj.addr}/{obj.name} ', #学校类型/school address/School name }class school:def __init__ (self,name,addr,type): Self.name=name self.addr=addr Self.type=type def __repr__ (self): Return ' School (%s,%s) '% (SELF.NAME,SELF.ADDR) def __str__ (self): return ' (%s,%s) '% (s ELF.NAME,SELF.ADDR) def __format__ (self, format_spec): # If Format_spec if not format_spec or Format_spec Not in format_dict:format_spec= ' Nat ' Fmt=format_dict[format_spec] return Fmt.format (obj=self) s1 =school (' oldboy1 ', ' Beijing ', ' private ') print (' From repr: ', repr (S1)) print (' From str: ', str (S1)) print (S1) ' str function or print function--- >OBJ.__STR__ () repr or interactive interpreter--->obj.__repr__ () if __str__ is not defined, then __repr__ is used instead of output note: The return value of both methods must be a string, otherwise throw an exception ' ' Print (Format (S1, ' Nat ')) print (Format (S1, ' TNA ')) print (foRmat (S1, ' Tan ')) print (Format (S1, ' asfdasdffd '))
Nine __slots__
What is 1.__slots__: A class variable, a variable value can be a list, a tuple, or an iterative object, or a string (meaning that all instances have only one data attribute) 2. Introduction: Using points to access attributes is the __dict__ property dictionary that accesses a class or object ( The dictionary of the class is shared, and each instance is independent) 3. Why use __slots__: A dictionary consumes a lot of memory, if you have a class with very few attributes, but there are many instances, in order to save memory you can use __slots__ to replace instances of __dict__ when you define __slots After __, __SLOTS__ will use a more compact internal representation for the instance. Instead of defining a dictionary for each instance, the instance is constructed from a small, fixed-size array, similar to a tuple or list. The attribute names listed in __slots__ are internally mapped to the specified small label for this array. A bad place to use __slots__ is that we can no longer add new properties to the instance, only those that are defined in __slots__. 4. Note: Many of the features of __slots__ depend on common dictionary-based implementations. In addition, classes that define __SLOTS__ no longer support some common class features, such as multiple inheritance. In most cases, you should only define __slots__ on classes that are often used as data structures, such as millions of instance objects in a program that need to create a class. A common misconception about __slots__ is that it can be used as an encapsulation tool to prevent users from adding new properties to an instance. Although the use of __slots__ can achieve this goal, but this is not its original intention. more is used as a memory optimizer tool. ' Class Foo: __slots__= ' x ' F1=foo () f1.x=1f1.y=2# error print (f1.__slots__) #f1不再有__dict__class Bar: __slots__= [' x ', ' Y '] N=bar () n.x,n.y=1,2n.z=3# error __slots__ use
Class Foo: __slots__=[' name ', ' Age ']f1=foo () f1.name= ' Alex ' F1.age=18print (f1.__slots__) f2=foo () f2.name= ' Egon ' F2.age=19print (f2.__slots__) print (foo.__dict__) #f1与f2都没有属性字典__dict__了, unified __slots__ tube, memory-saving probing
Ten __next__ and __iter__ implementing an iterator protocol
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' class Foo: def __init__ (self,x): self.x=x def __iter__ (self ): return self def __next__ (self): n=self.x self.x+=1 return Self.xf=foo (3) for I in F: print (i) Simple demonstration
Class Foo: def __init__ (self,start,stop): self.num=start self.stop=stop def __iter__ (self): Return self def __next__ (self): if Self.num >= self.stop: raise stopiteration n=self.num Self.num+=1 return Nf=foo (1,5) from collections import Iterable,iteratorprint (Isinstance (f,iterator)) as I in Foo (1,5): print (i)
11 __doc__
Class Foo: ' I am description information ' passprint (foo.__doc__)
Class Foo: ' I am description information ' passclass Bar (foo): passprint (bar.__doc__) #该属性无法继承给子类该属性无法被继承
12 __module__ and __class__
__MODULE__ represents the object of the current operation in that module
__CLASS__ represents the class of the object that is currently being manipulated
#!/usr/bin/env python#-*-coding:utf-8-*-class C: def __init__ (self): self.name = ' SB ' lib/aa.py
From LIB.AA Import cobj = C () print obj.__module__ # output LIB.AA, i.e.: Output module print obj.__class__ # output LIB.AA.C, i.e. output class
13 __del__
destructor, which automatically triggers execution when the object is freed in memory.
Note: If the resulting object is just a Python program-level (user-level), then no need to define __del__, if the resulting object will also initiate system calls to the operating system, that is, an object has both user-level and kernel-level resources, such as (open a file, create a database link), The system resource must be reclaimed while the object is purged, which is used for the __del__
Python's object-oriented advanced step