[英]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)
两个属性x
和y
。'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
代表x
, 1
代表y
)。 但是,它的速度较慢的attr所访问my_point1.x
, my_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.