python advanced object-oriented programming

Use __slots__

Reference Links: https://www.liaoxuefeng.com/wiki/1016959663602400/1017501655757856

  slots are tracking means, is to use a variable in the class in python, the main function is limited to the class attribute instance is bound only declared __slots__

Student class (Object): 
    __slots__ is = ( 'name', 'Age') # tuple by definition allows binding property name

  But the only instance of the current class (Student) act, not a subclass of work, if the sub-category also __slots__ this variable, you can bind a sub-class instance attribute is the parent class and subclass __slots__ and set

 

Use @property

  Reference Links: https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208

  This is a decorator, is the ability to make encapsulated data methods as instance attributes as use, why increase can encapsulate data way to do that, because they can be checked when setting property of the instance, but the instance call the method is better through the property to access as simple, though they are single line of code

  The python is native to achieve a decorator, it is to make way into property call

  How to use it, and decorators exactly the same way

  

  @property decorator attribute is read way into the property call. Then @property decorator and create another decorator @ score.setter, the decoration is in order to set the property way into the property call

  Note that a @ score.setter method can be provided on a plurality of write attributes,

Student class (Object): 
    COUNT = 0 

    @ Property # The following is a getter 
    DEF Score (Self): 
        return Self .__ Score 

    @ score.setter # Here is #setter, note that the following is the name of the function name called when the settings, and getter the same function name, is distinctive only to explain, but also can not work 
    DEF set_score (Self, value): 
        IF not isinstance (value, int): 
            ( '! int value the MUST Object') the raise ValueError 
        elif not 0 < value = <= 100: 
            the raise a ValueError ( 'value MUST BETWEEN 0 and 100') 
        the else: 
            Self .__ value Score = 

    @ # property property only if a @property wrapped, then this attribute is read-only, will set an error 
    def -difference (Self): 
        return-self.score 100

  @property widely used in the definition of class, allows users to write short code, while ensuring the inspection parameters, to avoid unexpected application errors

Screen class (Object): 
    @Property 
    DEF width (Self): 
        return Self .__ width 
    @ width.setter 
    DEF width (Self, value): 
        Self .__ = width value 
    
    @Property 
    DEF height (Self): 
        return Self .__ height 
    @width. setter which has been out of s.height 1024, I did not know why, finally found wrong here, because it is copied and then finish did not change, always make such a mistake, and mistakes last time not traceable 
    DEF height (Self, value): 
        Self .__ height = value 

    the @Property 
    DEF Resolution (Self): 
        return self.width self.height # * also note that the above error where you can change the width __width, __height solved 

IF the __name__ == "__main__": 
    S = Screen () 
    s.height = 768 
    s.width = 1024

    Print ( 'Resolution =', s.resolution) 
    IF s.resolution == 786432: 
        Print ( '! test passed') 
    the else: 
        Print ( '! test failed') 
    Pass

 

Multiple inheritance MaxIn

  Reference Links: https://www.liaoxuefeng.com/wiki/1016959663602400/1017502939956896

  python allow multiple inheritance, while others only allow a single integrated language (Java)

  In object-oriented design, it is common in different ownership relations to set up a hierarchy between classes, but will classify the relationship of cause a variety of different levels, will greatly increase the level of complexity, this design is not acceptable.

  The use of multiple inheritance allows a class inherits from more than one class, which has more than one parent class function

  In order to make the regulations clear, and the designation of the main level

  When the relationship between design classes are usually single inherited, if you need additional classes, to be achieved through multiple inheritance, this design is commonly referred to as MaxIn

  In order to better see the class inheritance, we'll add an extra class MaxIn suffix to indicate that he is not the main class

  MaxIn purpose is to increase the multiple functions of a class, so that only the design category MaxIn priorities to combine multiple functions through multiple inheritance, rather than designing complex hierarchical relationships, only need to select the different functions needed in class combined, you can quickly build a desired class

 

Custom class

  Reference Links: https://www.liaoxuefeng.com/wiki/1016959663602400/1017590712115904

  We define the class, in addition to the unusual features of the definition of the class, but also by defining some special functions such as __init__, etc. within the class to make the class has some additional functions, these functions are used to define special functions of

 

  __str __ () and __repr __ ()

  Character is displayed when modify the print examples

  

>>> print(Student('Michael'))
<__main__.Student object at 0x109afb190>

  Print out a bunch <__main__.Student object at 0x109afb190>, does not look good.

  Well defined __str __ () method

>>> 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)

  But also directly print out variables to knock them out of the original look

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

  This is because the variables are displayed __repr __ () instead __str __ (), is the difference between the two __str__()returns a string that users see, and __repr__()returns the string program developers to see, that is, __repr__()for debugging Services.

  The solution is to define a second __repr__(). But usually __str__(), and __repr__()the code is the same, so there is a lazy wording:

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

 

  __iter __ ()

  As already mentioned, we define the class is actually a data type, you can use isinstance () to determine if we want the definition of a class can be iterated that passed for loop, we can define __iter__ () function to implement this special

  The iterative method returns an object, and then the cycle will continue to call for an iteration object of __next __ () to get the next value, until it hits the wrong end of the cycle StopIterable

  Author cited an example to that deed Fibonacci number column, for example, defines a Fib class, can act on a for loop

Fib class (Object): 
    def the __init __ (Self): 
        self.a, self.b, = 0,. 1 # initializes two counters A, B 

    def the __iter __ (Self): 
        return Self # iteration object instance itself, so return to their 

    def __ the __next (Self): 
        self.a, self.b, self.b, =, + the self.b # self.a a calculated value 
        if self.a> 100000: # loop exit conditions 
            the raise the StopIteration () 
        return self.a # returns the next value

  result

>>> for n in Fib():
...     print(n)
...
1
1
2
3
5
...
46368
75025

 

  __getitem__

  If we want to define the class as the list of data types, can be accessed through the index, you can define __getitem __ () to achieve

class Fib (object): # is actually generated by re-execute cycle and then the value to be taken so that the end of the cycle, return the value, not taking from generating good results, because he was not used to the type of data stored 
    def __getitem __ ( Self, n-): 
        A, B =. 1,. 1 
        for X in Range (n-): 
            A, B = B, A + B 
        return A

  But this can not be achieved slice List function, if you want to achieve, you can still

class Fib(object):
    def __getitem__(self, n):
        if isinstance(n, int): # n是索引
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice): # n是切片
            start = n.start
            stop = n.stop
            if start is None:
                start = 0
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L

  If you want to step parameters and also negative slice accordingly to achieve, the authors say can

  If the object as dict, __getitem__()parameters can also be a key for the Object, for example str.

  Is the corresponding __setitem__()method, the object is deemed to be assigned to a list or set dict. Finally, there is a __delitem__()method for deleting an element.

  In short, by the above method, our own definition of the class behaved and comes with Python list, tuple, dict no difference, thanks to a dynamic language of "duck typing", do not need to force an interface inheritance.

 

  __getattr__

  By defining this function, we can access when using the example of an undefined property, return to this property, the principle is to create a property in this function and then return that returns a dynamic property

  When you call the property does not exist, Python will call __getattr__ to try to get a property. Note that only when you call the property does not exist, only to find this function

class Student(object):

    def __init__(self):
        self.name = 'Michael'

    def __getattr__(self, attr):
        if attr=='score':
            return 99

  Moreover, a function may return

class Student(object):

    def __getattr__(self, attr):
        if attr=='age':
            return lambda: 25

  However, the corresponding invocation also need to change, because the method call Well

>>> s.age()
25

  So far we have achieved access to the property is not defined, but we can now access any property, if we do not deal with this property in __getattr__, it will return None, if we want to respond only to a few specific properties, we need to make __getattr__ can throw an exception

class Student(object):

    def __getattr__(self, attr):
        if attr=='age':
            return lambda: 25
        raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)

  The authors say this method is very useful, you can put all calls to the properties and methods of a class of all dynamic process, it does not require any special means of.

  Author cited an example illustrates the dynamic application process for some cases of fully dynamic

  For example, to achieve a complete SDK dynamic invocation based on the URL to achieve,

Chain class (Object): 

    DEF the __init __ (Self, path = ''): 
        self._path = path 

    DEF __getattr __ (Self, path): # 
        return Chain ( '% S / S%'% (self._path, path)) # Why is it here to create an instance with China? 

    __ __str DEF (Self): 
        return self._path 

    __repr__ = __str__ 

# effect 
>>> Chain () status.user.timeline.list # # requested when such property is status.user.timeline.list chained calls. 
'/ Status / user / timeline / list '# returned

  It corresponds to a write method for each URL of the API in the SDK by __getattr __ () to achieve not only simple, but also do not change with the change of API

 

  __call__

  For instance it can call itself

Student class (Object): 
    DEF the __init __ (Self, name): 
        the self.name = name 

    DEF the __call __ (Self): 
        Print ( '. My name IS S%'% the self.name) 

# call method 
>>> s = Student ( 'Michael') 
>>> S () # Self parameters do not pass 
My name is Michael.

  __call__ can also define parameters, in this case, call the object is the same as the function calls and

  So you can put an object as a function, the function as objects, as already lacks a fundamental difference between the two.

  If you put an object as a function, the function itself in fact be created dynamically at run-out, because the class instance is created out of the run that way, we will blur the boundaries of objects and functions.

  How to determine whether a variable is an object or function? In fact, more often, we need to determine whether an object can be called, the object can be called is a Callabletarget, such as with the above-defined functions and our __call__()class instance:

>>> callable(Student())
True
>>> callable(max)
True
>>> callable([1, 2, 3])
False
>>> callable(None)
False
>>> callable('str')
False

  By Callable () can be called when an object is determined whether an object

  

Use the enumeration class

  Reference Links: https://www.liaoxuefeng.com/wiki/1016959663602400/1017595944503424

  Limited fixed object instance and class called enum class, such as season, month, etc.

  python provides Enum class

from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

  So we get the Monthtype of enumeration class that can be directly used Month.Janto refer to a constant, or enumeration of all its members:

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

  valueProperty is automatically assigned to members of the intconstants from the default 1start counting.

  If more accurate control of enumerated type, available from EnumCustom P class derived:

Import the Enum enum from, UNIQUE 

@Unique 
class Weekday (the Enum): 
    the Sun of the Sun # = 0 value is set to 0, may also be set to another value 
    Mon =. 1 
    Tue = 2 
    Wed =. 3 
    Thu =. 4 
    Fri. 5 = 
    Sat = 6

  @uniqueDecorators can help us check to ensure no duplicates.

  Visible, both with member names referenced enumeration constants, and can be obtained directly from the enumeration constant value for value.

  EnumIt can be a group of related constants defined in a class, and the class is not changed, and the members can be compared directly.

 

Appreciated metaclass, ORM

  Reference Links: https://www.liaoxuefeng.com/wiki/1016959663602400/1017592449371072

  Notes (in fact, are copied): https://www.cnblogs.com/Gaoqiking/p/10744253.html

  

  

Guess you like

Origin www.cnblogs.com/Gaoqiking/p/11575325.html