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 Callable
target, 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 Month
type of enumeration class that can be directly used Month.Jan
to refer to a constant, or enumeration of all its members:
for name, member in Month.__members__.items(): print(name, '=>', member, ',', member.value)
value
Property is automatically assigned to members of the int
constants from the default 1
start counting.
If more accurate control of enumerated type, available from Enum
Custom 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
@unique
Decorators 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.
Enum
It 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