Multiple inheritance
Class Student (Man,oldman):
Pass
You can inherit multiple parent classes, have their methods, and if there is a parent class that has the same method, which one to use before
Custom Classes
It is important to note that a variable or function name such as __xxx__ is similar to __slots__, which has a special purpose in Python.
We already know the use of __slots__, and we know it with the __len__ () method so that class can act on the Len () function.
__str__
Let's first define a student class and print an instance
Class STUDENTC (): def __init__ (self,name): self.__name = Nameprint (Studentc (' cc '))
--<__main__. Studentc Object at 0x0000000000b48b00>
Print out a lump of ugly, we define the __str__ () method, return a nice-looking string
Class STUDENTC (): def __init__ (self,name): self.__name = name def __str__ (self): return ' STUDENTC Object (name:%s) '% Self.__nameprint (STUDENTC (' cc ')) # Studentc object (NAME:CC)
Return here without knocking print
But the direct knock variable is run under the shell, it's still not good to print.
1 2 3 |
>>> s = student ( ' Michael ' ) >>> s <__main__. student object at 0x109afb310 > |
This is because the direct display of the variable calls is not __str__ (), but __repr__ (), the difference is that __str__ () returns the string that the user sees, and __repr__ returns the string that the program developer sees, that is, __repr__ () is for debugging services
The solution is to define a __repr__ () again. But usually two code is the same, can be lazy
Class STUDENTC (): def __init__ (self,name): self.__name = name def __str__ (self): return ' STUDENTC Object (name:%s) '% self.__name __repr__ = __str__
__iter__
If a class wants to be used for a in loop, a __iter__ () method must be implemented, the method returns an iterative object, and the __next__ () method of the iteration object is constantly called to get the next value of the loop until the loop is exited when a stopiteration error is encountered
Class Fib (): def __init__ (self): Self.__a,self.__b = 0,1 def __iter__ (self): return self def __ Next__ (self): self.__a,self.__b = self.__b,self.__a + self.__b if self.__a >1000: raise Stopiteration else: return self.__afor x in Fib (): print (x)
__getitem__
Although the FIB instance can be used for a for loop, it looks a bit like the list, but it is not used as a list, for example, to take the Fifth Element
Class Suv (): def __getitem__ (self,n): A, B = 0,1 for x in range (n): A, B = b,a+b return aprint ( Fib () [3])
The list also has slicing functionality, which is not available here, because we don't know what is coming in to make a judgment.
Isinstance (N,slice) Slice is the type of slice. There are negative numbers and so do not deal with really want to fully implement the words need to add a lot
__getattr__
Normally, when we call a method or property of a class, if it doesn't exist, it will be an error.
To avoid this, in addition to adding a score attribute, Python has another wit, which is to write a __getattr__ () method that dynamically returns a property
Class Su (): def __init__ (self): self.name = ' cc ' def __getattr__ (self, item): If Item = = ' Score ': return ' score ' Print (Su ().)
When the called property does not exist, such as Score,python will attempt to invoke __getattr__ (self, ' score ') to try to get the property, so we have a chance to return the value of score
The return function is also possible
Class Student (): def __init__ (self): self.name = ' cc ' def __getattr__ (self, item): If Item = = ' Age ': return Lambda:25print (Student (). Age ())
Returns a function that is modified to student () when called. Age ()
Note that __getattr__ is called only if no attribute is found, and existing properties, such as name, do not find in __getattr__
Also, if the unknown attribute is not processed, if the output is judged. will return none, and to have class respond only to a specific number of properties, we will throw a attributeerror error as agreed
Class Student (): def __init__ (self): self.name = ' cc ' def __getattr__ (self, item): If Item = = ' Age ': return lambda:25 raise Attributeerror (' No with%s '%item) print (Student (). AC ())
It's actually okay. All properties and method invocations of a class are all dynamically processed and do not require any special means
What is the nature of this fully dynamic invocation and what does it actually do? The function is to make a call to a completely dynamic situation.
As an example,
Many websites now have rest APIs, such as Sina Weibo, and the URL of the watercress call API is similar
Http://api.server/user/friends
If you want to write the SDK, to the URL corresponding to the API to write a method, it is exhausting, and once the API changes, the SDK will be changed
With fully dynamic __getaattr__ we can write a chain call
Class Chain (): def __init__ (self,ab= ""): self._path =ab def __getattr__ (self, path): print (' Self._ Path =%s, Path =%s '% (Self._path,path)) return Chain ('%s/%s '% (Self._path,path)) def __str__ (self): return self._path __reper__ = __str__c = Chain (). Status.user.time.listprint (c)
1 2 3 4 5 |
self ._path = ,path = status self ._path = / status ,path = user self ._path = / status / user ,path = time self ._path = / status / user / time ,path = list / status / user / time / list |
Property does not exist, each time the __getattr__ method is called, the current Self._path + property name is returned, and is obtained by _path, accumulating until no attribute
Print a value that returns Self._path
__call__
An object instance can be associated with its own properties and methods, and when we invoke an instance method, we use Instance.methond () to invoke it. Can be called directly on the instance itself, in Python the answer is yes
Any class, you just need to define a __call__ () method to invoke the instance directly
Class Students (): def __init__ (self,name): self.name = name def __call__ (self): print (' myname is%s '% Self.name) S1 = Students (' s1 ') S1 ()
__CALL__ () can also define parameters. Making a direct call to an instance is like a function call, so you can actually see the function as an object, because there's no fundamental difference between the two.
If you look at the object as a function, then the function itself can be created dynamically during the run, so we blur the bounds of the object and the function.
So how do you tell if a variable is an object or a function? In fact, we just need to determine whether an object can be called, the object that can be called is a callable object, such as the function and the class instance of the __call__ () we defined above
Print (callable (Student)) print (callable ([1,2,34])) Print (callable (None)) Print (Callable (' str '))
Quick understanding of Python's Custom classes