【问题标题】:properties that are lists, assigning to index作为列表的属性,分配给索引
【发布时间】:2014-07-08 16:11:43
【问题描述】:

当使用属性来获取/设置属性列表时,适用于单个对象的相同样板代码似乎不适用于容器。 (或者,确实如此,但我做错了。)

例子:

>>> class A(object):
...     def __init__(self, x, y):
...             self.x = x
...             self.y = y
...     @property
...     def pos(self):
...             return [self.x, self.y]
...     @pos.setter
...     def pos(self, xy):
...             self.x, self.y = xy
... 
>>> Stick = A(10, 20)
>>> Stick.x
10
>>> Stick.y
20
>>> Stick.pos
[10, 20]
>>> Stick.pos = [5, 10]
>>> Stick.x
5
>>> Stick.y
10
>>> Stick.pos
[5, 10]

到目前为止一切顺利;但是,当尝试分配给Stick.pos[0] 时,我遇到了麻烦。

>>> Stick.pos[0] = 70
>>> Stick.x
5
>>> Stick.pos
[5, 10]

现在,当然,可能根本不会这样做,而只是直接分配给obj.x,但它确实让我想知道如果假设只有obj.pos 属性允许分配。 pos 是一个属性时,有没有办法成功分配给obj.pos[i]

【问题讨论】:

    标签: python python-2.7 properties


    【解决方案1】:

    这不起作用,因为当您调用 Stick.pos[0] 时,您正在调用 pos 的 getter,它返回一个列表对象,其中包含两个等于 self.xself.y 的整数,但不是实际引用self.xself.y。该列表的状态不会在您的班级内部维护,因此您对其所做的更改会丢失。

    但是,您可以通过在内部将 xy 存储在 list 中并使用 property 获取/设置它们来获得此行为:

    class A(object):
        def __init__(self, x, y): 
            self.xy = [x, y]
    
        @property
        def pos(self):
            return self.xy
    
        @pos.setter
        def pos(self, xy):
            self.xy = xy
    
        @property
        def x(self):
            return self.xy[0]
    
        @x.setter
        def x(self, x): 
            self.xy[0] = x 
    
        @property
        def y(self):
            return self.xy[1]
    
        @y.setter
        def y(self, y): 
            self.xy[1] = y 
    

    输出:

    >>> Stick = A(10, 20)
    >>> Stick.x
    10
    >>> Stick.y
    20
    >>> Stick.pos
    [10, 20]
    >>> Stick.pos = [5,10]
    >>> Stick.x
    5
    >>> Stick.y
    10
    >>> Stick.pos
    [5, 10]
    >>> Stick.pos[0] = 70
    >>> Stick.x
    70
    >>> Stick.pos
    [70, 10]
    

    【讨论】:

    • 啊,反向角度方法 :) 是的,我知道 obj.pos 正在调用吸气剂,我想我只是希望 @property 装饰器有一些魔力负责索引分配。嗯,这对我的目的来说可能一样好。
    • 虽然我想在那一点上,真正的答案是obj.pos 可能不应该是@property,只是一个属性,让obj.xobj.y 成为属性。所以obj.xy 也可以是obj.pos = [x, y],然后就可以直接使用了,是吗?
    • @Stick 是的,如果您除了返回 self.xy 之外没有对 pos 属性做任何事情,那么它根本不需要成为属性。
    猜你喜欢
    • 1970-01-01
    • 2021-11-23
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    相关资源
    最近更新 更多