【问题标题】:Python property setter decoration of a list object列表对象的 Python 属性设置器装饰
【发布时间】:2013-05-04 05:15:50
【问题描述】:
globalList = []
class MyList:
    def __init__(self):
        self.myList = [1, 2, 3]

    @property
    def myList(self):
        return self.myList.extend(globalList)
    @myList.setter
    def myList(self):
        return self.myList
mL1 = MyList()
print("myList: ", mL1.myList)
mL1.myList.append(4)
print("after appending a 4, myList: ", mL1.myList)

我的目标是能够调用评估 myList 实例属性和全局对象 globalList 的 mL1.myList,但这是错误:

Traceback (most recent call last):
  File "C:\Documents and Settings\Administrator\Desktop\Dropbox\sandbox.py", line 14, in <module>
    mL1 = MyList()
  File "C:\Documents and Settings\Administrator\Desktop\Dropbox\sandbox.py", line 6, in __init__
    self.myList = [1, 2, 3]
TypeError: myList() takes 1 positional argument but 2 were given

我应该怎么做才能解决这个问题?

【问题讨论】:

  • 我不确定您要做什么,但您似乎在滥用属性。属性设置器(您使用myList.setter 创建的)是在您执行mL1.myList = something 时调用的。它需要接受另一个参数,即属性要设置为的值something。如果你想要的只是能够阅读mL1.myList,那你为什么还需要一个二传手呢?你想让二传手做什么?

标签: python list decorator setter


【解决方案1】:

您的代码存在许多问题。可能最大的问题是您不能为您的属性赋予与它读取的基础属性相同的名称。如果在您的myList getter 中,您执行self.myList,这将导致无限递归,因为为了找出self.myList 是什么,它必须再次调用属性getter。

为避免这种情况,您应该让 getter 和 setter 引用一些其他属性,通常名称相同但前面有一个下划线。也就是说,对于您的情况,使用“隐藏”属性 _myList 来存储属性获取/设置的值。

其次,您的属性设置器需要接受您要设置属性的值的参数,并且需要将基础属性设置为该值。

最后,您返回的是extend 的结果,但extend 修改了列表并返回None,因此您的代码将导致None 作为mL1.myList 的值。

您的代码应该看起来更像这样:

globalList = []
class MyList(object):
    def __init__(self):
        self.myList = [1, 2, 3]

    @property
    def myList(self):
        return self._myList + globalList
    @myList.setter
    def myList(self, val):
        self._myList = val

如果您使用的是 Python 3,那么您可以使用 class MyList: 而不是 class MyList(object):

【讨论】:

  • 清除我的一些误解!谢谢。
猜你喜欢
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 2013-03-25
  • 2014-06-21
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
相关资源
最近更新 更多