python属性:listlike obj

2024-05-29 02:01:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个具有类似列表属性的对象。这就是我的意思。在

class Unit:

    def __init__(self):
        self.val = 0

class Bundle:

    def __init__(self, N=3):
        self.units = [ Unit() for i in range(N) ]

    def getvals(self):
        return [ unit.val for unit in self.units ]

    def setvals(self, vals):
        for i, val in enumerate(vals):
            self.units[i].val = val

    vals = property(getvals, setvals)

现在,这个对象的行为与预期不符。在

^{pr2}$

因此“b.vals=x”和“b.setvals(x)”语句是不等价的。你能告诉我为什么吗?以及如何使它正常工作吗?在


Tags: 对象inself列表forinitdefunit
2条回答

为了完成Martijn Pietersanswer,这可能是您想要的答案,我忍不住展示了一些在Python中可以做的非常奇特的事情,当我发现它们时,这让我非常惊讶。我想你会发现它们有用,或者给你一些未来的想法。在

1。Python list是一个对象,因此可以从list扩展类

这将使您的“Bundle”对象继承内置list对象的所有方法,并允许您向其添加新方法。在

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Unit(object):
  def __init__(self):
    self.val = 0
  def __repr__(self):
    return "%s %s val=%s" % (type(self), hex(id(self)), self.val)

class Bundle(list):
  def __init__(self, N=3):
    super(Bundle, self).__init__()
    self.extend([ Unit() for i in range(N) ])
  @property
  def vals(self):
    return [ unit.val for unit in self]
  @vals.setter
  def vals(self, vals):
    vals = vals[0:min(len(self), len(vals))] # if len(vals) > len(self), self[i] would break
    for i, val in enumerate(vals):
      self[i].val = val

if __name__ == "__main__":
  bundle = Bundle()  
  print "Bundle: %s" % bundle
  newUnit = Unit()
  bundle.append(newUnit)
  print "Bundle: %s" % bundle
  bundle.vals = [1, 2, 3, 4, 5, 6]
  print "Bundle (reassigned): %s" % bundle

请注意,我稍微修改了属性定义,使它们成为decorator,但基本思想保持不变。在

2。您可以覆盖某些内置方法,并使一个行为不是list的对象list

请注意,此代码仅用于示例目的。它有一个可怕的设计,一个可怕的OOP使用,它的行为将是非常混乱的每个人(甚至对Guido van Rossum。。。好吧,也许不是为了他,但我相信如果他在一个真正的节目里看到它,他会哭的)这是一个。。。的。。。错误的代码,但我认为这有助于理解如何重写内置方法。另外,它缺少很多方法来覆盖Bundle类作为一个真正的list对象,但是我有点累了:-)检查Emulating container types和Python文档的下一点,Additional methods for emulation of sequence types以获得完整的引用。在

^{pr2}$

希望这有点帮助。玩得开心点!在

在Python2中,property仅适用于新样式对象;您的Bundle类必须从^{继承:

class Bundle(object):
    ...

更正后,该属性将按预期工作:

^{pr2}$

相关问题 更多 >

    热门问题