Python namedtuple使用詳解

@author StormMa
@date 2017-06-12


生命不息,奮鬥不止!


Python的collections模塊在基礎數據類型的基礎上,提供了幾個額外的數據類型:namedtuple, defaultdict, deque, Counter, OrderedDict等,其中defaultdict和namedtuple是兩個很實用的擴展類型。我一貫的風格就是學一個數據類型,就想去看看源碼,雖然看不太懂,但是總比不看的強,之前java的集合源碼閱讀也是基於這樣一個目的。今天就從使用和源碼的角度來看一下namedtuple。

namedtuple是繼承自tuple的子類。namedtuple創建一個和tuple類似的對象,而且對象擁有可訪問的屬性。

定義namedtuple

類的聲明

class NamedTuple(tuple):
    _fields = ...  # type: Tuple[str, ...]

    def __init__(self, typename: str, fields: Iterable[Tuple[str, Any]], *,
                 verbose: bool = ..., rename: bool = ..., module: Any = ...) -> None: ...

    @classmethod
    def _make(cls, iterable: Iterable[Any]) -> NamedTuple: ...

    def _asdict(self) -> dict: ...
    def _replace(self, **kwargs: Any) -> NamedTuple: ...

定義一個namedtuple的User類型

User = collections.namedtuple('User', ['age', 'name'])
或者
User = collections.namedtuple('User', 'age, name')
或者
User = collections.namedtuple('User', 'age name')

對應源碼

def namedtuple(typename, field_names, verbose=False, rename=False):
    """Returns a new subclass of tuple with named fields.

    >>> Point = namedtuple('Point', ['x', 'y'])
    >>> Point.__doc__                   # docstring for the new class
    'Point(x, y)'
    >>> p = Point(11, y=22)             # instantiate with positional args or keywords
    >>> p[0] + p[1]                     # indexable like a plain tuple
    33
    >>> x, y = p                        # unpack like a regular tuple
    >>> x, y
    (11, 22)
    >>> p.x + p.y                       # fields also accessable by name
    33
    >>> d = p._asdict()                 # convert to a dictionary
    >>> d['x']
    11
    >>> Point(**d)                      # convert from a dictionary
    Point(x=11, y=22)
    >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fields
    Point(x=100, y=22)

    """

    # Validate the field names.  At the user's option, either generate an error
    # message or automatically replace the field name with a valid name.
    if isinstance(field_names, str):
        field_names = field_names.replace(',', ' ').split()
    field_names = list(map(str, field_names))

創建對象

user = User = (21, 'StormMa')
或者
user = User(age=21, name='StormMa')
或者
user = User._make([21, 'name']) 

屬性訪問

# 年齡
user.age

# 姓名
user.name

轉換成字典

user_dict = user._asdict()

# 訪問 
user_dict['name']
user_dict['age']

替換屬性值

user2 = user._replace(age=20)

本文來自我的個人站點: http://blog.stormma.me,轉載請註明出處!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章