2

谁能举个例子?

在类和命名元组中使用变量有什么区别?

4

4 回答 4

9

的返回值namedtuple 一个类。没有黑魔法。您不需要将命名元组返回“转换”为类;它完全返回了那个。

namedtuple创建一个继承自 的新类__builtin__.tuple。当你调用 时namedtuple('Point', 'x y')(1, 0),你得到的是(1, 0)具有以下语法糖的元组对象:

  • 一个__dict__映射,其中{'x': 1, 'y', 0}
  • 两个属性x和分别y调用__getitem__(0)__getitem__(1)
  • __repr__返回的方法'Point(x=1, y=0)'

除此之外,它只是一个元组对象。它的属性和属性数量是不可变的。

但是,我怀疑你的意思是你想要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})
于 2012-05-05T04:13:33.533 回答
3

很模糊的问题。

我想你的意思是像这样的结构

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因为双重查找和附加功能执行(参见源代码 - 它有很好的文档说明如何namedtuple工作)

myPoint2只能由 attr 访问my_point2.xmy_point2.y. 通过 attr 访问myPoint2比通过 attr 访问更快myPoint1

此外,如果您不使用__slots__,每个实例都会消耗更多内存,因为为每个实例创建了属性/方法的字典(用于动态调整它们 - 添加或删除属性、字段、方法等),无论插槽是否只为类创建一次。

很快,namedtuple返回tuple subclass通常用作tuple,但指定的属性也可以访问哪些数据。

于 2012-05-05T06:40:11.847 回答
1

我认为 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')
于 2017-07-07T02:21:20.083 回答
0

从集合导入 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())
于 2018-03-08T17:36:27.683 回答