简体   繁体   English

如何将“命名元组”更改为 Python 中的类?

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

Can anyone give an example?谁能举个例子?

What's the difference between using variables in classes and in namedtuples?在类和命名元组中使用变量有什么区别?

The return value of namedtuple is a class. namedtuple的返回值一个类。 No dark magic.没有黑魔法。 You do not need to "convert" a namedtuple return into a class;您不需要将 namedtuple 返回“转换”为一个类; it returned exactly that.它返回的正是那个。

namedtuple creates a new class that inherits from __builtin__.tuple . namedtuple创建一个继承自__builtin__.tuple的新类。 When you call namedtuple('Point', 'x y')(1, 0) , you're getting is the tuple object (1, 0) with the following syntactic sugar:当您调用namedtuple('Point', 'x y')(1, 0) ,您得到的是具有以下语法糖的元组对象(1, 0)

  • a __dict__ mapping where {'x': 1, 'y', 0} __dict__映射,其中{'x': 1, 'y', 0}
  • two properties x and y that call __getitem__(0) and __getitem__(1) respectively.分别调用__getitem__(0)__getitem__(1)两个属性xy
  • a __repr__ method that returns 'Point(x=1, y=0)'返回'Point(x=1, y=0)'__repr__方法

Other than this, it's just a tuple object.除此之外,它只是一个元组对象。 Its attributes and number of attributes are immutable.它的属性和属性数量是不可变的。

However, I suspect you mean you want to take nametuple('Point', 'x, y') and instead get:但是,我怀疑您的意思是您想要使用nametuple('Point', 'x, y')而不是:

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

In this case you are misusing nametuple , and should instead be using type :在这种情况下,您误用了nametuple ,而应该使用type

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

Very vague question.很模糊的问题。

I suppose that you mean constructions like我想你的意思是像这样的结构

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

and

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

myPoint1 is faster in access by index my_point1[0] , my_point1[1] (where 0 stands for x , and 1 stands for y ). myPoint1通过索引my_point1[0]my_point1[1]访问速度更快(其中0代表x1代表y )。 But it's slower in access by attr my_point1.x , my_point1.y because of double lookups and additional function executing (see source - it's well documentated about how does namedtuple work)但是,它的速度较慢的attr所访问my_point1.xmy_point1.y因为双查找和附加功能执行(见源-这是很documentated如何做namedtuple工作)

myPoint2 is only accessable by attr my_point2.x , my_point2.y . myPoint2只能通过 attr my_point2.x , my_point2.y访问。 And accessing by attr myPoint2 is faster than accessing by attr myPoint1 .并且通过 attr myPoint2访问比通过 attr myPoint1访问更快。

Also if you dont use __slots__ , every instance would consume more memory because dict of attrs/methods is created for every instance (for dynamically tune them - add or remove attrs, fields, methods, etc), whether slots is created once for class only.此外,如果您不使用__slots__ ,每个实例都会消耗更多内存,因为为每个实例创建了 attrs/methods 的dict (用于动态调整它们 - 添加或删除 attrs、字段、方法等),是否仅为类创建一次.

Shortly, namedtuple returns tuple subclass that commonly works as tuple , but which data is also accessable by specified attrs.很快, namedtuple返回通常用作tuple tuple subclass ,但指定的属性也可以访问哪些数据。

I think OP wants to be explit about the class definition for a data structure which is currently a namedtuple.我认为 OP 想要详细说明当前是命名元组的数据结构的类定义。 namedtuple([...], verbose=True) is likely what you're looking for: 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')

from collections import namedtuple as nt从集合导入 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