簡體   English   中英

如何將“命名元組”更改為 Python 中的類?

[英]How to change “namedtuples” into classes in Python?

誰能舉個例子?

在類和命名元組中使用變量有什么區別?

namedtuple的返回值一個類。 沒有黑魔法。 您不需要將 namedtuple 返回“轉換”為一個類; 它返回的正是那個。

namedtuple創建一個繼承自__builtin__.tuple的新類。 當您調用namedtuple('Point', 'x y')(1, 0) ,您得到的是具有以下語法糖的元組對象(1, 0)

  • __dict__映射,其中{'x': 1, 'y', 0}
  • 分別調用__getitem__(0)__getitem__(1)兩個屬性xy
  • 返回'Point(x=1, y=0)'__repr__方法

除此之外,它只是一個元組對象。 它的屬性和屬性數量是不可變的。

但是,我懷疑您的意思是您想要使用nametuple('Point', 'x, y')而不是:

class Point:
    def __init__(x, y):
        self.x = x
        self.y = y

在這種情況下,您誤用了nametuple ,而應該使用type

def init(self, x, y):
    self.x, self.y = x, y
Point = type('Point', (object,), {'__init__': init})

很模糊的問題。

我想你的意思是像這樣的結構

myPoint1 = namedtuple('myPoint1','x y')

class myPoint2(object):
    __slots__ = ['x','y']
    def __init__(self, x, y)
        self.x = x
        self.y = y

myPoint1通過索引my_point1[0]my_point1[1]訪問速度更快(其中0代表x1代表y )。 但是,它的速度較慢的attr所訪問my_point1.xmy_point1.y因為雙查找和附加功能執行(見源-這是很documentated如何做namedtuple工作)

myPoint2只能通過 attr my_point2.x , my_point2.y訪問。 並且通過 attr myPoint2訪問比通過 attr myPoint1訪問更快。

此外,如果您不使用__slots__ ,每個實例都會消耗更多內存,因為為每個實例創建了 attrs/methods 的dict (用於動態調整它們 - 添加或刪除 attrs、字段、方法等),是否僅為類創建一次.

很快, namedtuple返回通常用作tuple tuple subclass ,但指定的屬性也可以訪問哪些數據。

我認為 OP 想要詳細說明當前是命名元組的數據結構的類定義。 namedtuple([...], verbose=True)可能是您要查找的內容:

>>> from collections import namedtuple
>>> Pooper = namedtuple('Pooper', ('poop_length','poop_width'))
>>> Pooper(7.5, 1.5)
Pooper(poop_length=7.5, poop_width=1.5)
>>> Pooper = namedtuple('Pooper', ('poop_length','poop_width'), verbose=True)
class Pooper(tuple):
    'Pooper(poop_length, poop_width)'
    __slots__ = ()
    _fields = ('poop_length', 'poop_width')

    def __new__(_cls, poop_length, poop_width):
        'Create new instance of Pooper(poop_length, poop_width)'
        return _tuple.__new__(_cls, (poop_length, poop_width))

    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new Pooper object from a sequence or iterable'
        result = new(cls, iterable)
        if len(result) != 2:
            raise TypeError('Expected 2 arguments, got %d' % len(result))
        return result

    def __repr__(self):
        'Return a nicely formatted representation string'
        return 'Pooper(poop_length=%r, poop_width=%r)' % self

    def _asdict(self):
        'Return a new OrderedDict which maps field names to their values'
        return OrderedDict(zip(self._fields, self))

    def _replace(_self, **kwds):
        'Return a new Pooper object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('poop_length', 'poop_width'), _self))
        if kwds:
            raise ValueError('Got unexpected field names: %r' % kwds.keys())
        return result

    def __getnewargs__(self):
        'Return self as a plain tuple.  Used by copy and pickle.'
        return tuple(self)

    __dict__ = _property(_asdict)

    def __getstate__(self):
        'Exclude the OrderedDict from pickling'
        pass

    poop_length = _property(_itemgetter(0), doc='Alias for field number 0')

    poop_width = _property(_itemgetter(1), doc='Alias for field number 1')

從集合導入 namedtuple 作為 nt

human_nt = nt('Human_nt', 'name, age')
peter_nt = human_nt('Peter', 20)

class Human_cls (human_nt):
     def some_methods(self):
          pass

peter_cls = Human_cls(**peter_nt._asdict())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM