【问题标题】:Python property on a list列表中的 Python 属性
【发布时间】:2016-09-30 14:14:38
【问题描述】:

我是 Python 新手,我刚刚发现了这些属性。当我在一个简单的变量上尝试它时它工作得很好,但我不能让它在一个列表上工作。执行下面的代码时,它将调用两次 getter 而不是 setter。我知道在我的示例中,该属性没有附加值,但它是为了简化。

class C:
    def __init__(self):
        self._x = [1, 2, 3]

    @property
    def x(self):
        print("getter")
        return self._x
    @x.setter
    def x(self, value):
        print("setter")
        self._x = value

c = C()
c.x[1] = 4
print(c.x[1])

有人知道我做错了什么吗?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    setter/getter 仅在直接获取或设置属性时使用:

    c.x           # getter
    c.x = [1,2,3] # setter
    

    如果您修改属性中的元素,您将获取该属性,然后设置相应的元素。你的例子相当于

    d = c.x       # getter again
    d[1] = 4
    

    您也可以使用__getitem____setitem__ 直接允许设置和获取特定项目。

    class C:
        def __init__(self):
            self._x = [1, 2, 3]
    
        @property
        def x(self):
            print("getter")
            return self._x
        @x.setter
        def x(self, value):
            print("setter")
            self._x = value
    
        def __getitem__(self, idx):
            print("getitem")
            return self._x[idx]
    
        def __setitem__(self, idx, value):
            print("setitem")
            self._x[idx] = value
    
    >>> c = C()
    >>> c[1] = 3
    setitem
    >>> c.x
    getter
    [1, 3, 3]
    >>> c[2]
    getitem
    3
    

    【讨论】:

    • 你真的要调用 c[1] = 3 吗?!如果班级有两个列表怎么办?!
    • @MahshidZeinaly 如果该类有两个列表,那么您可能不应该使用__getitem____setitem__ 方法,否则您需要对其进行大量修改。我在编写代码时只考虑了一个列表,但没有更多信息,这有点模棱两可。什么时候该换?还是两者兼而有之?
    • 你能解释一下为什么当类有两个列表时我们不应该装饰 getitemsetitem 吗?
    • @Frank 因为它变得模棱两可。您想用__getitem__ 索引您的两个列表中的哪一个?如果它不是模棱两可的,那就去做吧——它只要求你需要提前考虑。
    • 我明白了。我以为都是@x.setter 装饰的。谢谢!
    【解决方案2】:

    您的c.x[1] = 4 实际上分为两个操作:

    1. 获取 c 的“x”属性(=> getter)
    2. 在结果对象上设置项目。

    没有简单的方法可以摆脱这种情况。但无论如何,最终它会如你所愿,不是吗?

    setter 会被调用,如果你写了类似的东西:

    c.x = another_list
    

    【讨论】:

    • 好的,所以无法使用语法为 c.x[1]=4 的 setter 属性?
    • 没有。 MSeifert 的回答显示了可能的替代方案。
    猜你喜欢
    • 2021-03-26
    • 2019-06-27
    • 2014-10-24
    • 2019-01-25
    • 2016-01-13
    • 2011-02-13
    • 2010-09-10
    • 2022-06-15
    • 2011-01-30
    相关资源
    最近更新 更多