访问 setter 中 属性 的当前值

Accessing current value of property in setter

在 Python 中,是否可以 访问其 setter 中的 class 变量的当前值?

例如:

# Getter
@property
# ...

# Setter
@position.setter
def position(self, value):
    # Do something with current value...
    # self.position, self.__position, position and __position don't seem to work

    # Update position with the given value
    self.__position = value

    # Do something with the new value...

C# 中的等价物是:

private Position position;

public Position Position
{
    get
    {
        // ...
    }

    set
    {
        // Do something with the current value...

        // Update position field with given object
        position = value;

        // Do something with the new value...
    }
}

更新
这是一个最小的、完整的和可验证的例子,可以更好地说明我的问题:

class C:
    def __init__(self):
        self.x = 2

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, value):
        print(self.x)
        self.__x = value
        print(self.x)

c = C()

抛出以下错误:

AttributeError: 'C' object has no attribute '_C__x'

发生这种情况是因为 setter 尝试在更新变量之前打印变量的当前值,而 setter 在 x 中设置为 2 时 运行 __init__,此时 x 以前没有被赋值(没有要打印的当前值)。

您在 __init__ 中设置了 self.x(使用 setter)。但是在你x.setterprint(self.x)(使用getter)之前实际设置你的值。

您可以定义一个 default-value(例如 class 属性)以使其工作:

class C:
    __x = None

    def __init__(self):
        self.x = 2

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, value):
        print(self.x)
        self.__x = value
        print(self.x)

>>> c = C()
None
2

请注意,双下划线变量受 "name mangling" 约束,惯例是使用单下划线变量。

另一种方法是 try 访问它,如果它不可用,那么 return 做其他事情(或做其他事情):

class C:
    def __init__(self):
        self.x = 2

    @property
    def x(self):
        try:
            return self.__x
        except AttributeError:
            # I return "None" here but you could also do something else
            return None

    @x.setter
    def x(self, value):
        print(self.x)
        self.__x = value
        print(self.x)

产生相同的结果:

>>> c = C()
None
2