跳转至

Chapter 1 The Python Data Model

概要: Python中的数据模型概览

创建时间: 2022.11.27 18:26:09

更新时间: 2022.11.27 20:09:54

字符串格式化

优选 f-string 形式

随机选取可迭代容器的元素

不要自己造轮子,使用标准库的 random.choice

更Pythonic的数据模型

  1. 使你自己定义的数据类的行为更加符合标准数据模型的风格
  2. 为自定义数据类增加 特殊方法(special method),如 __getitem__, __len__ 等(见下示例1-1)
Python
import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits
                                        for rank in self.ranks]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]

操作符(operator)重载

Python
"""
vector2d.py: a simplistic class demonstrating some special methods

It is simplistic for didactic reasons. It lacks proper error handling,
especially in the ``__add__`` and ``__mul__`` methods.

This example is greatly expanded later in the book.

Addition::

    >>> v1 = Vector(2, 4)
    >>> v2 = Vector(2, 1)
    >>> v1 + v2
    Vector(4, 5)

Absolute value::

    >>> v = Vector(3, 4)
    >>> abs(v)
    5.0

Scalar multiplication::

    >>> v * 3
    Vector(9, 12)
    >>> abs(v * 3)
    15.0

"""


import math

class Vector:

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'Vector({self.x!r}, {self.y!r})'

    def __abs__(self):
        return math.hypot(self.x, self.y)

    def __bool__(self):
        return bool(abs(self))

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)

    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)

抽象基类ABC (abstract base class)

对标准库的 collections.abc ,其实现的接口范式可用下图概括
image.png
从上图可以看出以下两方面内容
Python中所有的 Collection ABC 必须实现

  1. 可迭代:支持 for 迭代和 unpacking 解包操作
  2. 可求大小:支持使用内建的 len 获取数据长度
  3. 容器化:支持 in 操作符获取容器内元素

Collection中三大数据类型

  1. 序列 Sequence ,比如 liststr
  2. 映射 Mapping ,比如 dictcollections.defaultdict
  3. 集合 Set ,比如 setfrozenset

特殊方法(Special method)

关于每个方法的具体说明,参考 3. Data model — Python 3.11.0 documentation

非操作符类型

类别 方法名
String/bytes representation __repr__ __str__ __format__ __bytes__ __fspath__
Conversion to number __bool__ __complex__ __int__ __float__ __hash__ __index__
Emulating collections __len__ __getitem__ __setitem__ __delitem__ __contains__
Iteration __iter__ __aiter__ __next__ __anext__ __reversed__
Callable or coroutine execution __call__ __await__
Context management __enter__ __exit__ __aexit__ __aenter__
Instance creation and destruction __new__ __init__ __del__
Attribute management __getattr__ __getattribute__ __setattr__ __delattr__ __dir__
Attribute descriptors __get__ __set__ __delete__ __set_name__
Abstract base classes __instancecheck__ __subclasscheck__
Class metaprogramming __prepare__ __init_subclass__ __class_getitem__ __mro_entries__

操作符类型

操作符类别 操作符 方法名
Unary numeric - + abs() __neg__ __pos__ __abs__
Rich comparison < <= == != > >= __lt__ __le__ __eq__ __ne__ __gt__ __ge__
Arithmetic
+ - * / // % @ divmod() round() ** pow() __add__ __sub__ __mul__ __truediv__ __floordiv__ __mod__ __matmul__ __divmod__ __round__ __pow__
Reversed arithmetic (arithmetic operators with swapped operands) __radd__ __rsub__ __rmul__ __rtruediv__ __rfloordiv__ __rmod__ __rmatmul__ __rdivmod__ __rpow__
Augmented assignment arithmetic += -= *= /= //= %= @= **= __iadd__ __isub__ __imul__ __itruediv__ __ifloordiv__ __imod__ __imatmul__ __ipow__
Bitwise & | ^ << >> ~ __and__ __or__ __xor__ __lshift__ __rshift__ __invert__
Reversed bitwise (bitwise operators with swapped operands) __rand__ __ror__ __rxor__ __rlshift__ __rrshift__
Augmented assignment bitwise &= |= ^= <<= >>= __iand__ __ior__ __ixor__ __ilshift__ __irshift__

为什么len(obj)速度比obj.length()更快?

No method is called for the built-in objects of CPython: the length is simply read from a field in a C struct.

即对内建对象而言,使用 len() 时直接读取的C结构的数据,因此速度要远快于自定义的 obj.lenth()

参考