Smooth python, Fluent Python XII notes (inherited)

Chapter 12: Inheritance advantages and disadvantages

 

12.1 subclass built-in types a lot of trouble

Before Python2.2, built-in types (such as list or dict) can not subclass. After Python2.2, built-in types can be subclassed, but there are important considerations: built-in types covered by the special class method is not called (written in C).

In [194]: class DoppelDict(dict): 
     ...:     def __setitem__(self, key, value): 
     ...:         super().__setitem__(key, [value] * 2) 
     ...:                                                                                          

In [195]: dd = DoppelDict(one=1)                                                                   

In [196]: dd                                                                                       
Out[196]: {'one': 1}

In [197]: dd['two'] = 2                                                                            

In [198]: dd                                                                                       
Out[198]: {'one': 1, 'two': [2, 2]}

In [199]: dd.update(three=3)                                                                       

In [200]: dd                                                                                       
Out[200]: {'one': 1, 'two': [2, 2], 'three': 3}

In [201]:  

 Through the code book, the effect can be seen only when defined __setitem__ assignment produced, additional initialization, no dictionary update __setitem__ using a modified method, using the original method of the superclass.

__missing__ method was able to work as expected in this terrible situation, although this is just a special case.

 

If other class built-in methods of the class method calls, if covered, it will not be called.

In [202]: class AnswerDict(dict): 
     ...:     def __getitem__(self, key): 
     ...:         return 42 
     ...:                                                                                          

In [203]: ad = AnswerDict(a='foo')                                                                 

In [204]: ad['a']                                                                                  
Out[204]: 42

In [205]: d = {}                                                                                   

In [206]: d.update(ad)                                                                             

In [207]: d['a']                                                                                   
Out[207]: 'foo'

In [208]: d                                                                                        
Out[208]: {'a': 'foo'}

In [209]:       

 This should be more intuitive, because you're only in your own class which defines __getitem__, all methods in addition object to call you (upgrade here), and will not use you to modify, or use the parent class when the list.

 

Built-in types directly subclassing (e.g. dict, str, list), since the built-in type of method usually ignored method covered by a user. Do not subclass built-in types,

It should be a subclass of these three modules

In [211]: collections.UserDict                                                                     
Out[211]: collections.UserDict

In [212]: collections.UserList                                                                     
Out[212]: collections.UserList

In [213]: collections.UserString                                                                   
Out[213]: collections.UserString

In [219]: import collections 
     ...:  
     ...: class DoppelDict2(collections.UserDict): 
     ...:      
     ...:     def __setitem__(self, key, value): 
     ...:         return super(DoppelDict2, self).__setitem__(key, [value] *2) 
     ...:      
     ...:     def __getitem__(self, item): 
     ...:          
     ...:         return self.data[item] * 2 
     ...:                                                                                          

In [220]:                                                                                          

In [220]: dd = DoppelDict2(one=1)                                                                  

In [221]: dd                                                                                       
Out[221]: {'one': [1, 1]}

In [222]: dd['one']                                                                                
Out[222]: [1, 1, 1, 1]

In [223]: dd.get('one')                                                                            
Out[223]: [1, 1, 1, 1]

In [224]: dd.update(three=3)                                                                       

In [225]: dd                                                                                       
Out[225]: {'one': [1, 1], 'three': [3, 3]}

In [226]:    

 As mentioned above, __getitem__ attribute data dictionary in self.data inside, I add.

In [226]: class AnswerDict2(UserDict): 
     ...:     def __getitem__(self, key): 
     ...:         return 42 
     ...:          
     ...:                                                                                          

In [227]: ad = AnswerDict2(a='foo')                                                                

In [228]: ad['a']                                                                                  
Out[228]: 42

In [229]: ad                                                                                       
Out[229]: {'a': 'foo'}

In [230]: d = dict()                                                                               

In [231]: d.update(ad)                                                                             

In [232]: d                                                                                        
Out[232]: {'a': 42}

In [233]: d['a']                                                                                   
Out[233]: 42

 Can be found through this and other objects when calling the update, the ad calls __getitem__ method, due to the inherited UserDict, all with the revised methodology.

 

12.2 multiple inheritance and method resolution order.

 

class A(object):
    def ping(self):
        print('ping', self)


class B(A):
    def pong(self):
        print('pong', self)



class C(A):
    def pong(self):
        print('PONG', self)



class D(B, C):

    def ping(self):
        super(D, self).ping()
        print('post-ping', self)

    def pingpong(self):
        self.ping()
        super().ping()
        self.pong()
        super().pong()
        C.pong(self)

 

In [254]: d = D()                                                                                  

In [255]: d.pong()                                                                                 
pong <__main__.D object at 0x10e0a4cd0>

In [256]: C.pong(d)                                                                                
PONG <__main__.D object at 0x10e0a4cd0>

In [257]: D.__mro__                                                                                
Out[257]: (__main__.D, __main__.B, __main__.C, __main__.A, object)

In [258]:      

 The above is performed in two ways, one is performed by the instance of the parent class pong, executed in the order of __mro__.

There is also a property directly through the class perform, display execution, rape this little feeling.

 

General delegate the implementation of the parent class, use super () is better.

In [259]: d.ping()                                                                                 
ping <__main__.D object at 0x10e0a4cd0>
post-ping <__main__.D object at 0x10e0a4cd0>

 A first output line, based on a layer __mro__ looking directly to class A is performed inside this property.

 

     ...:     def pingpong(self): 
     ...:         self.ping() 
     ...:         super().ping() 
     ...:         self.pong() 
     ...:         super().pong() 
     ...:         C.pong(self) 

 result

d.pingpong()                                                                             
ping <__main__.D object at 0x10e0a4cd0>
post-ping <__main__.D object at 0x10e0a4cd0>
ping <__main__.D object at 0x10e0a4cd0>
pong <__main__.D object at 0x10e0a4cd0>
pong <__main__.D object at 0x10e0a4cd0>
PONG <__main__.D object at 0x10e0a4cd0>

 

Finally, a method of execution.

Prime Minister execution self.ping (), that they have this property, after performing self.ping () output

Two execution

The first ping <__ main __. D object at 0x10e0a4cd0>, is performed to the ping parent class's parent class A,

The second post-ping <__ main __. D object at 0x10e0a4cd0> execution, inside their own method.

Next super.ping (), ping is performed a parent class of the parent class A

self.pong and Super (). pong result will be identical, since there is no self pong property itself, the need to look for the parent class of the property by sequentially __mro__.

super (). pong is through __mro__ to find the parent class property.

Finally, a parent attribute that is running through explicit manner.

 

A code book back, demonstrate some of the several classes __mro__

In [269]: bool.__mro__                                                                             
Out[269]: (bool, int, object)

In [270]: import numbers                                                                           

In [271]: numbers.Integral.__mro__                                                                 
Out[271]: 
(numbers.Integral,
 numbers.Rational,
 numbers.Real,
 numbers.Complex,
 numbers.Number,
 object)

In [272]: import io                                                                                

In [273]: io.BytesIO.__mro__                                                                       
Out[273]: (_io.BytesIO, _io._BufferedIOBase, _io._IOBase, object)

In [274]: io.TextIOWrapper.__mro__                                                                 
Out[274]: (_io.TextIOWrapper, _io._TextIOBase, _io._IOBase, object)

In [275]:  

 

The back of the book describes the inheritance and Django using Tkinter classes in view of my limited ability, practical operation of two modules basically nothing, so I can not tell a lot of the book to understand.

We can only look back.

 

 

 

Guess you like

Origin www.cnblogs.com/sidianok/p/12132908.html
Recommended