Smooth python, Fluent Python eleventh chapter notes

Interface: abstract base class from protocol to.

In this chapter, we do not know the translation problem, or my ability, to see not really understand, can simply record your own understanding. After some time to return to read.

 

First informal protocol interface, each class (except abstract base class), both interfaces.

Protected property and private property is not in the interface.

The interface is a subset of the object of the disclosed method, so that objects play a particular role in the system

Interface is the way to achieve a specific set of roles, there is no agreement with the inheritance relationship, a class may implement multiple interfaces, thereby playing of roles.

Protocol sequence is one of the most basic Python agreement.

In [29]: from collections.abc import Sequence                                                      

In [30]: class Foo: 
    ...:     def __getitem__(self, pos): 
    ...:         return range(0, 30, 10)[pos] 
    ...:                                                                                           

In [31]: f = Foo()                                                                                 

In [32]: f[1]                                                                                      
Out[32]: 10

In [33]: for i in f:print(i)                                                                       
0
10
20

In [34]: 20 in f                                                                                   
Out[34]: True

In [35]: isinstance(f, Sequence)                                                                   
Out[35]: False

In [36]:  

 __Getitem__ achieve the above definition of the part of the sequence of the agreement, it is clear that it is not a subclass of the Sequence, although there is no __iter__ and __Container__ but still be for the cycle call, and can be used in

In [35]: isinstance(f, Sequence)                                                                   
Out[35]: False

In [36]: from collections import Iterable                                                          
/usr/local/bin/ipython:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  #!/usr/local/opt/python/bin/python3.7

In [37]: isinstance(f, Iterable)                                                                   
Out[37]: False

 I remember the teacher said, could be for the cycle call is iterable, obviously, f can be for the cycle call, but not iterables, or have strict __iter__ is the iterable.

 

 

11.3 Use monkey pudding implement the protocol.

Monkey patch before to find out about it, we will know the name, now the book is very detailed introduction, but also practical use.

Examples of the object is not initially have this property, by adding its class instance attribute, then it is with this method, generally less.

The In [46 is]: Import Collections 
    ...:   
    ...: Card collections.namedtuple = ( 'Card', 'Rank SUIT') 
    ...:   
    ...: class Frenchdeck: 
    ...: ranks = [STR ( n) for n in range (2 , 11)] + list ( 'JQKA') # card numbers and the color assigned to the class attribute 
    ...:   
    ...: suits = 'SPADES hearts'.split Diamonds Clubs () 
    ...:   
    ...: DEF __init __ (Self): # generate a list of style production with a deck of cards 
    ...: self._cards = [card (Rank, SUIT) for Rank in self.ranks 
    ...: for SUIT self.suits in] 
    ...:   
    ...: DEF __len __ (Self): 
    ...: return len (self._cards) 
    ...:  
    ...: def __getitem __ (self, item): # define the [] value will be used. 
    ...: return self._cards [Item] 
    ...:   
    ...: DEF __repr __ (Self): 
    ...: F return 'R & lt self._cards {!}' 
    ...:                                                                                            

the In [47]: Desk = Frenchdeck ()                                                                        

the In [48]: Desk [:. 5]                                                                                   
Out [48]: 
[Card (Rank = '2', SUIT = 'SPADES'), 
 Card (Rank = '2', SUIT = 'Diamonds'), 
 Card (Rank = '2', SUIT = 'Clubs'), 
 Card (Rank = '2', SUIT = 'hearts'),

In [49]: shuffle(desk)                                                                             
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-49-1b00429a849a> in <module>
----> 1 shuffle(desk)

/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/random.py in shuffle(self, x, random)
    276                 # pick an element in x[:i+1] with which to exchange x[i]
    277                 j = randbelow(i+1)
--> 278                 x[i], x[j] = x[j], x[i]
    279         else:
    280             _int = int

TypeError: 'Frenchdeck' object does not support item assignment

In [50]: def set_card(deck, position, card): 
    ...:     deck._cards[position] = card 
    ...:      
    ...:                                                                                           

In [51]: Frenchdeck.__setitem__ = set_card                                                         

In [52]: shuffle(desk)                                                                             

In [53]: desk[:5]                                                                                  
Out[53]: 
[Card(rank='Q', suit='clubs'),
 Card(rank='4', suit='diamonds'),
 Card(rank='10', suit='hearts'),
 Card(rank='9', suit='spades'),
 Card(rank='5', suit='diamonds')]

 Monkeys pudding by adding cards to the first chapter, the front __setitem__ lack of attributes, shuffle can not be used for alignment, implements the protocol part of the variable sequence either by adding __setitem__ behind the object.

 

So-called duck typing is no need to focus on specific types of objects, as long as the realization of a specific agreement either, no inheritance.

 

 

Subclass of an abstract base class defines 11.5

 

In [54]: from collections.abc import MutableSequence                                               

In [55]: class Mu(MutableSequence): 
    ...:     ... 
    ...:                                                                                           

In [56]: mu = Mu()                                                                                 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-56-c234f3d4f57f> in <module>
----> 1 mu = Mu()

TypeError: Can't instantiate abstract class Mu with abstract methods __delitem__, __getitem__, __len__, __setitem__, insert

 There are 16 collections.abc abstract base class, where I inherited MutableSequence, it can be seen from the given __delitem__, __getitem__, __len__, __setitem__, insert, belonging to the abstract methods must be redefined subclass.

 

According to the book inherit MutalbeSquence FranchDeck

collections.abc Import 

Card collections.namedtuple = ( 'Card', 'Rank SUIT') 


class Frenchdeck2 (collections.abc.MutableSequence): 
    ranks = [STR (n-) for n-in Range (2,. 11)] + List ( ' JQKA ') # card numbers and the color assigned to the class attribute 
    suits =' SPADES hearts'.split Diamonds Clubs () 

    DEF the __init __ (Self): # create a formula with a list of cards 
        self._cards = [card (rank, SUIT) for Rank in self.ranks 
                       for SUIT in self.suits] 

    DEF __len __ (Self): method # abstract class inheritance 
        return len (self._cards) 

    DEF the __getitem __ (Self, Item): # define the [] values will used. 
        return self._cards [item] # abstract methods inherited class 

    def __delitem __ (self, key) : Method # abstract class inheritance 
        del self._cards [key]

    def __setitem __ (self, key, value): Method # abstract class inheritance 
        self._cards [Key] = value 

    DEF INSERT (Self, index: int, value) -: Method # abstract class inheritance> None 
        self._cards.insert (index, value) 

    DEF __repr __ (Self): 
        return F 'R & lt self._cards {!}' 


IF the __name__ == '__main__': 
    Deck = Frenchdeck2 () 
    deck.insert (0,. 1)

 All the abstract methods are defined, whatever you do not have to.

At the same time some of your abstract class method MutableSequence is also a process, such as remove, pop, extend, __ iadd__

In [78]: deck[0]                                                                                   
Out[78]: 1

In [79]: deck.pop()                                                                                
Out[79]: Card(rank='A', suit='hearts')

In [80]: deck.pop()                                                                                
Out[80]: Card(rank='A', suit='clubs')

In [81]: deck.extend('123')                                                                        

In [82]: deck.remove('2')   

 

collections.abc16 a base class and I am more interested in is the Callable Hashable is to test whether the object can be called hash.

In [83]: from collections.abc import Callable, Hashable                                            

In [84]: isinstance(print, Callable)                                                               
Out[84]: True

In [85]: isinstance(print, Hashable)                                                               
Out[85]: True

In [86]: isinstance(list, Hashable)                                                                
Out[86]: True

In [87]: isinstance(list(), Hashable)                                                              
Out[87]: False

In [88]: callable(list)                                                                            
Out[88]: True

In [89]:  

Abstract base class Callable callable function with the same effect, Hashable only tested with this abstract class.

 

11.6.2 digital abstract base class column

numbers of packages

The official explanation link:

https://docs.python.org/zh-cn/3.7/library/numbers.html#numbers.Rational.numerator

Number

Complex

Real

The Rational (subclass is Intergal)

Integral

In [103]: from numbers import Integral                                                             

In [104]: isinstance(1,Integral)                                                                   
Out[104]: True

In [105]: from fractions import Fraction                                                           

In [106]: f = Fraction(3,4)                                                                        

In [107]: isinstance(f,Integral)                                                                   
Out[107]: False

In [108]: from numbers import Rational                                                             

In [109]: isinstance(f,Integral)                                                                   
Out[109]: False

In [110]: isinstance(f,Rational)                                                                   
Out[110]: True

In [111]:  

 Examples include Integral int, bool (int subclass)

Rational fraction containing more

 

11.7 and using the definition of an abstract base class.

In order to better learn abstract base class, the book defines an abstract base class, and inherits two subclasses, a virtual sub-columns.

abc Import 

class Tombila (abc.ABC): 
    
    @ abc.abstractmethod 
    DEF the Load (Self, Iterable): 
        "" "add elements from iterable" "" 
        
    @ abc.abstractmethod 
    DEF Pick (Self): 
        Print (of the type (Self) name__ + .__ 'iS Working Pick') 
        "" "randomly delete elements and returns 
        if the instance is null, this method throws" LookupError " 
        " "" 
    
    DEF loaded (Self): 
        "" "If there is at least one element, returns True, otherwise False "" " 
        return BOOL (self.inspect ()) 

    DEF Inspect (Self): 
        " "" returns a sorted tuples constituting a current element "" " 
        items = [] 
        the while True: 
            the try:
                items.append(self.pick())
            except LookupError:
                break 
        self.load (items) # returns the read 
        return tuple (sorted (items))

 The above is an abstract class, I defined some of the features inside the pick, when you can still call inherited by super.

 

11.7.1 Syntax Interpretation abstract base class.

After Python3.4 can do, it is written above the direct successor abc.ABC it.

Before 3.4

class Demo(metaclass=abc.ABCMeta):
    ...

 Python2 write:

class Demo(object):
    __metaclass__ = abc.ABCMeta

 

Before Python3.3 are:

@abc.abstractclassmethod
    @abc.abstractproperty
    @abc.abstractstaticmethod

 In the new do not, according to the principle of multi-layer decorator, you just put @ AbstractMethod on the innermost layer, you need to write on the top decoration, the same can be inherited by subclasses.

 

11.7.2 subclassing Tombola abstract base class.

 

First pumping line on the base class:

abc Import 

class Tombila (abc.ABC): 

    @ abc.abstractmethod 
    DEF the Load (Self, Iterable): 
        "" "add elements from iterable" "" 

    @ abc.abstractmethod 
    DEF Pick (Self): 
        Print (of the type (Self) name__ + .__ 'iS Working Pick') 
        "" "randomly delete elements and returns 
        if the instance is null, this method throws" LookupError " 
        " "" 

    DEF loaded (Self): 
        "" "If there is at least one element, returns True, otherwise False "" " 
        return BOOL (self.inspect ()) 

    DEF Inspect (Self): 
        " "" returns a sorted tuples constituting a current element "" " 
        items = [] 
        the while True: 
            the try:
                items.append(self.pick())
            except LookupError:
                break
        self.load(items)              # 返回读取
        return tuple(sorted(items))

if __name__ == '__main__':
    print(dir(Tombila))

 

 

The following functions are used to achieve this succession of three ways.

 

The first change happened, two base class methods are inherited, the second change to understand more, the base class methods are changed, the third virtual direct subclass does not inherit any base class methods.

Binggo # 
Import Random 

from Tombola Import Tombila 

class BingoCage (Tombila): 

    DEF the __init __ (Self, Item): 
        self._randomizer = random.SystemRandom () 
        self._items = [] 
        self.load (Item) # call the load method to achieve initialization 

    the Load DEF (Self, Iterable): 
        self._items.extend (Iterable) 
        self._randomizer.shuffle (self._items) 

    DEF Pick (Self): 
        the try: 
            return self._items.pop () 
        the except IndexError: # no data can pop up error, receiving IndexError, error reporting Look 
            the raise LookupError ( 'empty BingoCage from Pick') 

    DEF the __call __ (Self, args *, ** kwargs): # object becomes callable
        return self.pick () # book did not return, I added, otherwise the implementation of the object does not return a value 


IF __name__ == '__main__': 
    Bingo = BingoCage (the Range (10)) 
    Print (Bingo ()) 
    Print (Bingo .inspect ())

 

/usr/local/bin/python3.7 / Users / shijianzhong / study / Fluent_Python / XI /bingo.py 
. 6 
(0,. 1, 2,. 3,. 4,. 5,. 7,. 8,. 9) 

Process Finished with exit code 0

 The second Inheritance:

Random Import 

from Tombola Import Tombila 

class LotteryBlower (Tombila): 

    DEF the __init __ (Self, Iterable): 
        self._balls = List (Iterable) 

    DEF Load (Self, Iterable): 
        self._balls.extend (Iterable) 

    DEF Pick (Self): 
        the try: 
            position = random.randrange (len (self._balls)) # internal random numbers selected from a 
            return self._balls.pop (position) 
        the except a ValueError: # If len which is 0, a ValueError: empty for randrange Range () 
            The raise LookupError ( 'pick from empty LotteryBlower') # front crawl error return error required 

    DEF loaded (Self): 
        return BOOL (self._balls) 

    DEF Inspect (Self): 
        return tuple (the sorted (self._balls))


if __name__ == '__main__':
    lottery = LotteryBlower(range(10))
    print(lottery.pick())
    print(lottery.inspect())

 

/usr/local/bin/python3.7 / Users / shijianzhong / study / Fluent_Python / XI /lotto.py 
. 4 
(0,. 1, 2,. 3,. 4,. 5,. 6,. 7,. 8,. 9) 

Process finished with exit code 0

 

11.7.3 Tombola virtual subclass

Virtual subclass does not inherit the abstract base class registration, in other words, direct point, is the virtual sub-class with an abstract base class that was nothing to do.

You can not inherit or modify the abstract methods abstract base class, but in order to avoid operational errors, did not inherit it, so all the base class methods should rewrite it.

First on an extreme example does not inherit any base class.

from random import randrange

from tombola import Tombila



class A:
    ...

Tombila.register(A)



a = A()
print(isinstance(a, Tombila))
print(issubclass(A, Tombila))

 

/usr/local/bin/python3.7 /Users/shijianzhong/study/Fluent_Python/第十一章/tombolist.py
True
True

Process finished with exit code 0

 You can see the code, the effect of virtual subclasses.

This is the code of the book:

Random Import randrange from 

from Tombola Import Tombila 



@ Tombila.register 
class TomboList (List): 

    DEF Pick (Self): # Self is the list itself 
        IF Self: 
            position = randrange (len (Self)) 
            return self.pop (position) 
        the else : 
            The raise LookupError ( 'empty Tombolist from POP') 

    Load = Load # list.extend equal list.extend direct method 

    DEF Loader (Self): 
        return BOOL (Self) 

    DEF Inspect (Self): 
        return tuple (the sorted (Self)) 

# Tombila.register (TomboList) which is written before Python3.3 

IF the __name__ == '__main__': 
    Tombo = TomboList (Range (10))  
    Print (tombo.pick ())
    Print (tombo.inspect ())
    print(tombo.load(range(3)))    # 等同与tombo.extend(range(3))
    print(tombo.inspect())
    print(TomboList.__mro__)

 

/usr/local/bin/python3.7 /Users/shijianzhong/study/Fluent_Python/第十一章/tombolist.py
1
(0, 2, 3, 4, 5, 6, 7, 8, 9)
None
(0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9)
(<class '__main__.TomboList'>, <class 'list'>, <class 'object'>)

Process finished with exit code 0

 Can be seen, there is no longer seen __mro__ base class Tombila.

I then thought for a moment, and if the base class method does not list the same name (originally did not), you can double inheritance.

 

Random Import randrange from 

from Tombola Import Tombila 




class TomboList (Tombila, List): 

    DEF Pick (Self): # Self is the list itself 
        IF Self: 
            position = randrange (len (Self)) 
            return self.pop (position) 
        the else: 
            The raise LookupError ( 'empty Tombolist from POP') 

    Load = Load # list.extend equal list.extend direct method 

    DEF Loader (Self): 
        return BOOL (Self) 

    DEF Inspect (Self): 
        return tuple (the sorted (Self)) 

# Tombila. register (TomboList) which is written before Python3.3 

IF the __name__ == '__main__': 
    Tombo = TomboList (Range (10)) 
    Print (tombo.pick ()) 
    Print (tombo.inspect ())
    print(tombo.load(range(3)))    # 等同与tombo.extend(range(3))
    print(tombo.inspect())
    print(TomboList.__mro__)

 

/usr/local/bin/python3.7 /Users/shijianzhong/study/Fluent_Python/第十一章/tombolist_1.py
9
(0, 1, 2, 3, 4, 5, 6, 7, 8)
None
(0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8)
(<class '__main__.TomboList'>, <class 'tombola.Tombila'>, <class 'abc.ABC'>, <class 'list'>, <class 'object'>)

Process finished with exit code 0

 Such a method is not, but the back of the book describes a virtual base class, some uses Python.

 

11.8 Tombola subclass test methods.

Doctest test module, and how I did not used, so I do not write, including the search for a useful virtual subclass code.

Tombila._abc_registry 
but I fail, no error this property.

 

11.9 Python using the register of the way.

Python will tuple, str, range, memoryview registered as a virtual sub-categories.

Squence.regiser(tuple)

....

This dictionary includes also registered to MutableMapple

MutableMapple.register(dict)

 

11.10 by the goose's behavior might like a duck

 

class Sruggle:
    def __len__(self):
        return 23



print(issubclass(Sruggle, Sized))
print(Sized.__subclasscheck__(Sruggle))

 Returns are true

Virtual subclass of this Sruggle not SIzed, but can not be a subclass.

But because Sized special __subclasscheck__ class.

Here I transcribe in accordance with the above code Sized original code:

import abc

class Sized(abc.ABC):

    __slots__ = ()

    @abc.abstractmethod
    def __len__(self):
        return 0

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Sized:
            if any("__len__" in B.__dict__ for B in C._mro__):
                return True
        return NotImplemented

 The book describes the principle issubclass no run, I think if there is __subclasshook__ priority should be to call the class method.

 

But generally __subclasshook__ with very little chance of their own with even less.

 

 

 

 

 

 

 

 

 

 

 

















 

Guess you like

Origin www.cnblogs.com/sidianok/p/12129223.html