Python's object-oriented advanced step

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.