Fluent Python

Chapter 1: Python data model

Special Methods are cool and are written like __special_method__. They are called by the Python framework to enable various functionality. We’re not supposed to call them directly (except for __init__ to call superclass constructor maybe).

Special Methods for Collection Objects

  1. __getitem__: Random-access operator.

  2. __len__: Provides a functionality to obtain length, with len(object).

Together, they allow the framework to do the following:

  1. Access any element with index (object[key]).

  2. Access n-th element from last with negative indexing (object[-index_from_last]).

  3. Obtain random element using random.choice.

  4. Slicing (object[key1:key2]) (TODO read more about slicing).

  5. Make the object iterable.

    for item in object:
      do_stuff(item)
    
  6. Generate a reverse iterator.

    for item in reverse(object):
      do_stuff(item)
    
  7. Enable querying for existance of an item by performing sequential scanning.

    Note

    Implement a __contains__ function, then in would use that one.

  8. If we provice a custom item_ranker function, then we can also sort the items in the object using sorted interface.

    def item_ranker(item):
      return rank(item)
    
    for item in sorted(object, item_ranker):
      do_stuff(item)
    

Special Methods for Numeric Objects

  1. __add__(self, other) implements self + other.

  2. __mul__(self, other) implements self * other.

  3. __abs__(self) implements abs(self).

  4. __repr__(self) implements a printable representation (enables print(object) and usage in %r).

  5. __str__(self) implements a string representation (enables str(object) and usage in %s).

  6. __bool__(self) returns True/False to be used in if/else/and/or/not.

    Note

    1. __repr__ usually encodes a hint about how to construct an object of the class as-well (e.g. MyClass(a=x, b=y)).

    2. __str__ may represent it as [x,y].

    3. In absence of a __str__, it falls back to __repr__.

    4. Delegate the task of representing items in object by using item!r inside format string.

      def __repr__(self):
        return f'MyClass(a={self.a!r}, b={self.b!r})'
      

Collections API

Refere to image 1.2 in the book for UML diagram. In a nutshell, any collection object should implement:

  1. Iterable to enable for.

  2. Sized to enable len.

  3. Container to enable in.

Specialization of Collection class:

  1. Sequence

  2. Mapping

  3. Set

Refer to table 1-1 and 1-2 in the book for a list of special methods for various functionalities.

Chapter 2: An Array of Sequences

Note

Each python object contains metadata fields (such as reference counts, type-information).

Sequences provide common functionalities such as iteration, slicing, sorting and concatenation.

Classification of Sequences

  1. Storage:

  1. Container Sequences: Contains pointers to python objects, potentially heterogeneous. Example: list/tuple.

  2. Flat Sequences: Contains a contiguous chuck of memory for homogenous python objects. Example: str/array.

  1. Mulatibility:

  1. Mutable Sequences: Items can be updated in-place. Example: list/array.

  2. Immutable Sequences: Items cannot be updated. Creates a new instance instead. Example: tuple/str.