如何使用 Python 创建带有属性的元组?

发布于 2024-12-11 16:24:07 字数 564 浏览 0 评论 0原文

我有一个类 WeightedArc 定义如下:

class Arc(tuple):

  @property
  def tail(self):
    return self[0]

  @property
  def head(self):
    return self[1]

  @property
  def inverted(self):
    return Arc((self.head, self.tail))

  def __eq__(self, other):
    return self.head == other.head and self.tail == other.tail

class WeightedArc(Arc):
  def __new__(cls, arc, weight):
    self.weight = weight
    return super(Arc, cls).__new__(arc)

这段代码显然不起作用,因为 self 没有为 WeightArc.__new__ 定义。如何将属性权重分配给 WeightArc 类?

I have a class WeightedArc defined as follows:

class Arc(tuple):

  @property
  def tail(self):
    return self[0]

  @property
  def head(self):
    return self[1]

  @property
  def inverted(self):
    return Arc((self.head, self.tail))

  def __eq__(self, other):
    return self.head == other.head and self.tail == other.tail

class WeightedArc(Arc):
  def __new__(cls, arc, weight):
    self.weight = weight
    return super(Arc, cls).__new__(arc)

This code clearly doesn't work, because self isn't defined for WeightArc.__new__. How do I assign the attribute weight to the WeightArc class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

虚拟世界 2024-12-18 16:24:07

原始代码的修复版本是:

class WeightedArc(Arc):
    def __new__(cls, arc, weight):
        self = tuple.__new__(cls, arc)
        self.weight = weight
        return self

另一种查看collections.namedtupleverbose选项的方法,以查看如何子类tuple<的示例/em>:

>>> from collections import namedtuple, OrderedDict
>>> _property = property
>>> from operator import itemgetter as _itemgetter
>>> Arc = namedtuple('Arc', ['head', 'tail'], verbose=True)
class Arc(tuple):
    'Arc(head, tail)' 

    __slots__ = () 

    _fields = ('head', 'tail') 

    def __new__(_cls, head, tail):
        'Create new instance of Arc(head, tail)'
        return _tuple.__new__(_cls, (head, tail)) 

    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new Arc 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 'Arc(head=%r, tail=%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 Arc object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('head', 'tail'), _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) 

    head = _property(_itemgetter(0), doc='Alias for field number 0')
    tail = _property(_itemgetter(1), doc='Alias for field number 1')

您可以剪切、粘贴和修改此代码,或者只是从其子类化,如 中所示命名元组文档

要扩展此类,请构建 Arc 中的字段:

WeightedArc = namedtuple('WeightedArc', Arc._fields + ('weight',))

The fixed-up version of your original code is:

class WeightedArc(Arc):
    def __new__(cls, arc, weight):
        self = tuple.__new__(cls, arc)
        self.weight = weight
        return self

Another approach to look at the verbose option for collections.namedtuple to see an example of how to subclass tuple:

>>> from collections import namedtuple, OrderedDict
>>> _property = property
>>> from operator import itemgetter as _itemgetter
>>> Arc = namedtuple('Arc', ['head', 'tail'], verbose=True)
class Arc(tuple):
    'Arc(head, tail)' 

    __slots__ = () 

    _fields = ('head', 'tail') 

    def __new__(_cls, head, tail):
        'Create new instance of Arc(head, tail)'
        return _tuple.__new__(_cls, (head, tail)) 

    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new Arc 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 'Arc(head=%r, tail=%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 Arc object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('head', 'tail'), _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) 

    head = _property(_itemgetter(0), doc='Alias for field number 0')
    tail = _property(_itemgetter(1), doc='Alias for field number 1')

You can cut, paste, and modify this code, or just subclass from it as shown in the namedtuple docs.

To extend this class, build off of the fields in Arc:

WeightedArc = namedtuple('WeightedArc', Arc._fields + ('weight',))
五里雾 2024-12-18 16:24:07

另一种查看 collections.namedtuple 详细选项的方法,以查看如何子类化元组的示例

更好的是,为什么我们自己不使用namedtuple呢? :)

class Arc(object):
    def inverted(self):
        d = self._asdict()
        d['head'], d['tail'] = d['tail'], d['head']
        return self.__class__(**d)

class SimpleArc(Arc, namedtuple("SimpleArc", "head tail")): pass

class WeightedArc(Arc, namedtuple("WeightedArc", "head tail weight")): pass

Another approach to look at the verbose option for collections.namedtuple to see an example of how to subclass tuple

Better yet, why not use namedtuple ourselves? :)

class Arc(object):
    def inverted(self):
        d = self._asdict()
        d['head'], d['tail'] = d['tail'], d['head']
        return self.__class__(**d)

class SimpleArc(Arc, namedtuple("SimpleArc", "head tail")): pass

class WeightedArc(Arc, namedtuple("WeightedArc", "head tail weight")): pass
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文