"Object-oriented advanced Python3"

Source: Internet
Author: User
Tags function definition ftp client

First, Isinstance and Issubclass1. isinstance (obj,cls) checks if obj is an object of class CLS
Class Foo (object):    Passobj=foo () print (Isinstance (obj, Foo))

Output

True

2. Issubclass (sub, super) check if the sub class is a derived class of super class
Class Foo (object):    passclass Bar (foo):    passprint (Issubclass (Bar, Foo))

Output

True

Second, reflection 1. Reflection definition

The concept of reflection, first proposed by Smith in 1982, is a capability (introspection) that a program can access, detect, and modify its own state or behavior.

2. Realization of Reflection

Python-oriented reflection in objects: manipulating Object-related properties in the form of strings. All things in Python are objects, and you can use reflection

Four functions that can be self-reflective, the following methods apply to classes and objects (all objects, the class itself is an object)

    • Hasattr (Object,name)

Determines whether an object has a Name property or a name method, returns a bool value, returns true with the name attribute, or FALSE. It is important to note that name is enclosed in parentheses.

>>> class Test (): ...     Name= "Xiaohua"     ... def run (self): ...             Return "Helloword" ...>>> t=test () >>> hasattr (t, "name") #判断对象有name属性True >>> hasattr (t, " Run ")  #判断对象有run方法True >>>

    • GetAttr (object, name, Default=none)

Gets the object's property or method, if it exists, prints the default value if it does not exist, and the default value is optional. It is important to note that if you are returning an object's method, the memory address of the method is returned, and if you need to run this method, you can add a pair of parentheses later.

>>> class Test (): ...     Name= "Xiaohua"     ... def run (self): ...             Return "Helloword" ...>>> t=test () >>> getattr (t, "name") #获取name属性, the presence is printed out. ' Xiaohua ' >>> getattr (t, "Run")  #获取run方法, there is a memory address for printing out the method. <bound method Test.run of <__main__.test instance at 0x0269c878>>>>> getattr (T, "Run") ()  # Gets the Run method, which is followed by parentheses to run the method. ' Helloword ' >>> getattr (t, "age")  #获取一个不存在的属性.  Traceback (most recent):  File ' <stdin> ', line 1, in <module>attributeerror:test instance have no Attribute ' age ' >>> getattr (t, "age", "Max")  #若属性不存在, returns a default value. ' @ ' >>>
    • SetAttr (object, name, values)

Assigns a value to the object's property and, if the property does not exist, first creates a re-assignment.

>>> class Test (): ...     Name= "Xiaohua"     ... def run (self): ...             Return "Helloword" ...>>> t=test () >>> hasattr (T, "age")   #判断属性是否存在False >>> setattr (t, " Age "," ")   #为属相赋值, and no return value >>> hasattr (t," age ")    #属性存在了True >>>
    • Delattr (object, name)

Delete the property with the object name named name.

General examples

Class Blackmedium:    feature= ' Ugly '    def __init__ (self,name,addr):        self.name=name        self.addr=addr    def sell_house (self):        print ('%s sell house '%self.name)    def rent_house (self):        print ('%s rent House '%self.name) b1 =blackmedium (' Evergrande ', ' Huilongguan ') #检测是否含有某属性print (Hasattr (B1, ' name ')) print (Hasattr (B1, ' Sell_house ')) #获取属性n =getattr (B1, ' Name ') print (n) func=getattr (B1, ' Rent_house ') func () # GetAttr (B1, ' aaaaaaaa ') #报错print (GetAttr (B1, ' aaaaaaaa ', ' nonexistent ah ') ) #设置属性setattr (B1, ' SB ', True) SetAttr (B1, ' Show_name ', Lambda self:self.name+ ' 123 ') print (b1.__dict__) print (B1.show_ Name (B1)) #删除属性delattr (B1, ' addr ') delattr (B1, ' Show_name ') #delattr (B1, ' show_name111 ') #不存在, error print (b1.__dict__)

Output

Truetrue Evergrande Evergrande Rent A house does not exist ah {' show_name ': <function <lambda> at 0x10c9e8f28>, ' SB ': True, ' addr ': ' Huilongguan ', ' name ': ' Evergrande ' } Evergrande 123{' SB ': True, ' name ': ' Evergrande '}

Class is also an object

Class Foo (object):    Staticfield = "old"    def __init__ (self):        self.name = ' 123 '    def func        : Return ' func '    @staticmethod    def Bar ():        return ' bar ' Print (GetAttr (foo, ' Staticfield ')) print (GetAttr (foo , ' func ')) print (GetAttr (Foo, ' Bar '))

Output

Old<function Foo.func at 0x10f89f488><function foo.bar at 0x10f89f510>

Reflection of the module

Import SYS                                                                                                  def s1 ():                               print (' s1 ')                                                                                             def s2 ():                               print (' s2 ')                                                                                             this_module = sys.modules[__name__]                                     Print (Hasattr (this_module, ' s1 '))   print (GetAttr (this_module, ' s2 '))   

Output

True<function S2 at 0x108f4d400>

3. Benefits of Reflection
    • Implement pluggable mechanisms

can be defined in advance interface, the interface is only after the completion of the actual execution, this implementation of Plug and Play, which is actually a ' late binding ', that you can pre-write the main logic (only define the interface), and then later to implement the interface function.

Programmer A does not implement functionality

Class FtpClient:    ' FTP client, but still has the ability to implement specific '    def __init__ (self,addr):        print (' Connecting server [%s] '%addr)        Self.addr=addr

But does not affect programmer B to continue to implement other logic, using reflection in advance to make judgments

#from Module Import ftpclientf1=ftpclient (' 192.168.1.1 ') if Hasattr (F1, ' get '): #判断方法是否实现    func_get=getattr (F1, ' ge T ')    Func_get () Else: print (    '----> Not present this method ')    print (' Handle Other logic ')

    • Dynamic Import module (based on reflection of the current module member)

Third, __setattr__,__getattr__,__delattr__
    • __getattr__

Intercept point number operation. This method is called with the property name as a string when an undefined property name and instance are performed in a point-number operation. If the inheritance tree can find the property, this method is not called

    • __setattr__

An assignment statement that intercepts all attributes. If this method is defined, SELF.ARRT = value becomes self,__setattr__ ("attr", value). This needs to be noted. When an attribute is assigned within the __setattr__ method, self.attr = value cannot be used, because he will call self,__setattr__ ("attr", value) again, resulting in an infinite recursive loop that eventually results in a stack overflow exception. Any instance property should be assigned by indexing an attribute dictionary, that is, using self.__dict__[' name ' = value.

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__ F1.xxxxxx is triggered only when a property is called with a point and the property does not exist

Output

----> from setattr{}----> from setattr{}----> from delattr{}----> from GetAttr: The property you are looking for does not exist

四、二次 processing
    • Packaging

Python provides a standard data type and a rich set of built-in methods, but in many scenarios we need to customize our own data types based on standard data types, adding/rewriting methods that use the inheritance we just learned Derived knowledge (other standard types can be processed two times in the following way)

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)

Output

[1, 2, 3, 4] [1, 2, 3, 4, 5]3[-123, 1, 2, 3, 4, 5][]

    • Authorized

Authorization is a feature of packaging, packaging a type is usually some customization of existing types, this practice can create new, modify or delete the functionality of the original product. Others remain as they are. The authorization process, that is, all updated functionality is handled by a part of the new class, but the existing functionality is granted to the object's default property.

The key to implementing authorization is to overwrite the __getattr__ method.

Class List:    def __init__ (self,seq,permission=false):        self.seq=seq        self.permission=permission    def Clear (self):        if not self.permission:            raise Permissionerror (' Don't allow the operation ')        Self.seq.clear ()    def __getattr__ (self, item):        return GetAttr (self.seq,item)    def __str__ (self):        return str (self.seq ) L=list ([]) # l.clear () #此时没有权限, throws an exception L.permission=trueprint (l) l.clear () print (L) #基于授权, gets the Insert method L.insert (0,- 123) print (L)

Output

[1, 2, 3] [][-123]

Wu, __str__,__repr__,__format__

Changing the object's string display __str__,__repr__

Self-Customizing formatted string __format__

    • __str__,__repr__

Let's first define a Student class and print an instance:

>>> class Student (object): ...     def __init__ (self, name): ...         Self.name = name...>>> Print (Student (' Michael ')) <__main__. Student Object at 0x109afb190>

Print out a bunch <__main__.Student object at 0x109afb190> , not pretty.

How can you print it well? Just define a good __str__() method and return a nice-looking string:

>>> class Student(object):...     def __init__(self, name):...         self.name = name...     def __str__(self):...         return ‘Student object (name: %s)‘ % self.name...>>> print(Student(‘Michael‘))Student object (name: Michael)

This kind of printed example, not only good-looking, but also easy to see the important data inside the instance.

But careful friends will find that the direct knocking variable print is not used, the printed example is not good to see:

>>> s = Student (' Michael ') >>> s<__main__. Student Object at 0x109afb310>

This is because the direct display of variable calls is not __str__() , but the __repr__() difference between the two is to return the string that the __str__() user sees, and the __repr__() string that the program developer sees, that __repr__() is, for debugging services.

The solution is to define one more __repr__() . But it's usually __str__() __repr__() the same as the code, so there's a lazy way to do it:

Class Student (object):    def __init__ (self, name):        self.name = name    def __str__ (self):        return ' Student object (name=%s) '% self.name    __repr__ = __str__

    • __format__
date_dic={    ' ymd ': ' {0.year}:{0.month}:{0.day} ',    ' dmy ': ' {0.day}/{0.month}/{0.year} ',    ' mdy ': ' {0.month }-{0.day}-{0.year} ',}class Date:    def __init__ (self,year,month,day):        self.year=year        Self.month=month        self.day=day    def __format__ (self, format_spec):        If isn't format_spec or Format_spec not in Date_dic:            Format_spec= ' Ymd '        Fmt=date_dic[format_spec]        return Fmt.format (self) d1=date (2016,12,29) print (Format (d1 ) Print (' {: mdy} '. Format (D1))

Output

2016:12:2912-29-2016

Liu, __del__

destructor, which automatically triggers execution when the object is freed in memory. This method is generally not defined, because Python is a high-level language, and programmers do not have to care about allocating and releasing memory because the work is done with the Python interpreter, so the destructor calls are automatically triggered by the interpreter when it is garbage collected.

Class Foo:    def __del__ (self):        print (' Execute delete ') F1=foo () print (' * * ') del f1print ('-------> ')

Output

* * Perform delete------->

Seven, __setitem__,__getitem__,__delitem__

When there is a dictionary-like operation in the instance

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, I execute ')        Self.__dict__.pop (item) f1=foo (' SB ') f1[' age ']=18f1[' age1 ']=19del f1.age1del ' f1[' age ']f1[' name ']= ' Alex ' Print (f1.__dict__)

Output

Del Obj.key when I execute del obj[key], I execute {' name ': ' Alex '}

Eight, __call__

The object is appended with parentheses to trigger execution.

Note: The execution of the construction method is triggered by the creation object, that is: Object = class name (), and the execution of the __call__ method is triggered by parentheses after the object, i.e.: Object () or Class () ()

Class Foo:    def __init__ (self):        pass        def __call__ (self, *args, **kwargs):        print (' __call__ ') obj = Foo () # Execute __init__obj ()       # Execute __call__

Ix. eval (), exec () 1, eval ()
    • Functions of the function

Evaluates the value of the specified expression. That is, the Python code it executes can only be a single operation expression (note that Eval does not support arbitrary assignment operations), rather than complex code logic, which is similar to a lambda expression.

    • function definition
eval (expression, Globals=none, Locals=none)
    • Parameter description:
    1. Expression: A required parameter, either a string or an arbitrary instance of the Code object (which can be created through the compile function). If it is a string, it is parsed and interpreted as a Python expression (using the Globals and locals parameters as global and local namespaces).
    2. Globals: An optional parameter that represents the global namespace (which holds the global variable) and, if provided, a Dictionary object.
    3. Locals: An optional parameter that represents the current local namespace (which holds local variables) and, if provided, can be any mapping object. If the parameter is ignored, then it will take the same value as globals.
    4. If both globals and locals are ignored, they will take the global namespace and local namespace of the eval () function called environment.
    • return value:
    1. If expression is a code object, and when the code object is created, the mode parameter of the compile function is ' exec ', then the return value of the eval () function is none;
    2. Otherwise, if expression is an output statement, such as print (), eval () returns a result of none;
    3. Otherwise, the result of expression expressions is the return value of the eval () function;
x = 10def func ():    y =    a = eval (' x + y ') print ('    A: ', a)    B = eval (' x + y ', {' X ': 1, ' Y ': 2})    print (' B: ', B '    c = eval (' x + y ', {' X ': 1, ' Y ': 2}, {' Y ': 3, ' Z ': 4})    print (' C: ', c)    d = eval (' Print (x, y) ')    pri NT (' d: ', D) func ()

Output

A:  30b:  3c:  410 20d:  None
    • Explanation of the output results:
    1. The globals and locals parameters of the variable a,eval function are ignored, so both the variable x and the variable y are obtained from the variable values in the scope of the Eval function's called environment, namely: X = ten, y = 20,a = x + y = 30
    2. For the variable B,eval function only provides the Globals parameter and ignores the locals parameter, so locals takes the value of the Globals parameter, namely: x = 1, y = 2,b = x + y = 3
    3. For the globals parameter and locals of the variable c,eval function are provided, then the Eval function finds the variable x from the full scope globals and finds the variable y from the local scope locals, namely: x = 1, y = 3, c = x + y = 4
    4. For variable d, because the print () function is not a calculation expression, no result is evaluated, so the return value is None

2.exec ()
    • Role of the function:

Execute Python code dynamically. This means that exec can execute complex python code, unlike the Eval function, which only evaluates to the value of an expression.

    • function definition:
EXEC (object[, globals[, locals])
    • Parameter description:
    1. Object: A required parameter that represents the python code that needs to be specified. It must be a string or a code object. If object is a string, the string is first parsed into a set of Python statements and then executed (unless a syntax error occurs). If object is a code object, it is simply executed.
    2. Globals: Optional parameter, same as eval function
    3. Locals: optional parameter, same as eval function
    • return value:

The return value of the EXEC function is always none.

It should be explained that exec is not a function in Python 2, but rather a built-in statement (statement), but there is a execfile () function in Python 2. It can be understood that Python 3 combines the functionality of the EXEC statement and execfile () functions into a new EXEC () function:

    • The eval () function differs from the EXEC () function:
    1. The eval () function evaluates only the values of a single expression, and the Exec () function can run code snippets on the fly.
    2. The eval () function can have a return value, and the EXEC () function return value is always none.
x = 10def func ():    y = $    a = EXEC (' x + y ')    print (' A: ', a)    B = Exec (' x + y ', {' X ': 1, ' Y ': 2})    print (' B: ', B '    c = exec (' x + y ', {' X ': 1, ' Y ': 2}, {' Y ': 3, ' Z ': 4})    print (' C: ', c)    d = EXEC (' Print (x, y) ')    PR Int (' d: ', D) func ()

Output

A:  noneb:  nonec:  None10 20d:  None

x = 10expr = "" "z = 30sum = x + y + zprint (sum)" "" Def Func ():    y =    exec (expr)    exec (expr, {' X ': 1, ' Y ': 2}    exec (expr, {' X ': 1, ' Y ': 2}, {' Y ': 3, ' Z ': 4}) func ()

Output

603334
    • Explanation of the output results:

The first two outputs, as explained above, do not explain too much, just as the Eval function does. For the last number 34, we can see that: x = 1, y = 3 is no doubt. About Z is still 30 instead of 4, which is actually very simple, we just need to understand the code execution process is possible, the execution process is equivalent to:

x = 1y = 2def func ():    y = 3    z = 4        z =    sum = x + y + z    print (sum) func ()

Ten, Meta Class 1. Definition of meta-class

A meta-class is used to control how a class is created, just as a class is the template that creates an object, and the primary purpose of the meta-class is to control the class's creation behavior

The result of the instantiation of the Meta class is the class that we define with class, just as an instance of the class is an object (the F1 object is an instance of the Foo class , and theFoo class is an instance of the type class )

Type is an inner Jianyuan class of python that is used to directly control the generated class, and any class defined in Python is actually an object instantiated by the type class.

2. How to create a class
    • Using the class keyword
Class Chinese (object):    country= ' China '    def __init__ (self,name,age):        self.name=name        self.age= Age    def talk (self):        print ('%s is talking '%self.name)
    • The process of manually simulating class creation classes: Split the steps to create a class and manually create

Preparatory work:

Creating a class is divided into three main parts

1 class name

Parent Class of Class 2

3 Class Body

#类名class_name = ' Chinese ' #类的父类class_bases = (object,) #类体class_body = "" "Country= ' China ' def __init__ (self,name,age):    self.name=name    self.age=agedef Talk (self):    print ('%s is talking '%self.name) ' ""

Step one (dealing with the namespace): The name of the class body definition is stored in the class namespace (a local namespace), we can define an empty dictionary in advance, and then use exec to execute the class body code (exec generates the namespace is similar to the real class process, Only the latter will deform the attributes that begin with __), generating the class's local namespace, which is the fill dictionary

Class_dic={}exec (Class_body,globals (), class_dic) print (class_dic) #{' country ': ' China ', ' Talk ': <function talk at 0x101a560c8>, ' __init__ ': <function __init__ at 0x101a56668>}

Step two: Call the Meta-class type (which can also be customized) to produce the class Chinense

Foo=type (Class_name,class_bases,class_dic) #实例化type得到对象Foo, which is the class Fooprint (foo) print (Type (foo)) that we define with class, print ( Isinstance (Foo,type)) ' <class ' __main__. Chinese ' ><class ' type ' >true '

We see that the type receives three parameters:

    1. The 1th parameter is the string ' Foo ', which indicates the class name

    2. The 2nd parameter is a tuple (object,) that represents all the parent classes

    3. The 3rd argument is a dictionary, here is an empty dictionary, indicating that no properties and methods are defined

Add: If the Foo class has inheritance, that is, Class Foo (Bar): .... is equivalent to type (' Foo ', (Bar,), {})

A class does not declare its own meta-class, and by default his meta-class is type, except that by using the meta-class type, the user can also customize the meta-class by inheriting the type

Self-customizing meta-Class Lite
Class Mytype (Type):    def __init__ (self,what,bases=none,dict=none):        print (what,bases,dict)    def __call__ (Self, *args, **kwargs):        print ('---> ')        obj=object.__new__ (self)        self.__init__ (Obj,*args,**kwargs)        return Objclass (metaclass=mytype):    def __init__ (self,name):        self.name=namer1=room (' Alex ') print ( R1.__DICT__)

"Object-oriented advanced Python3"

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.