类变量不更新



i具有以下基本类,涉及一个圆。我的问题是,当我直接使用C.直径(10(更新直径时,半径如何更新为5?如输出所示,它仍然在4:

from math import pi

class Circle:
    def __init__(self, radius=1):
        self.radius = radius
        self.diameter = self.radius * 2
    def diameter(self, diameter):
        self.diameter = diameter
        self.radius = self.diameter / 2
        return self.radius, self.diameter
    def area(self):
        return self.radius ** 2 * pi

c = Circle(3)
print("c.radius:", c.radius)
print("c.area():", c.area())
c.radius = 4  # change radius
print("c.radius:", c.radius)
print("c.area():", c.area())
c.diameter = 10  # change diameter
print("c.diameter:", c.diameter)
print("c.radius:", c.radius)

输出:

c.radius: 3
c.area(): 28.274333882308138
c.radius: 4
c.area(): 50.26548245743669
c.diameter: 10
c.radius: 4   <--- Radius should be 5, since the Radius is Diameter / 2

您有两件事名为 diameter

  • 实例上的属性,在__init__中使用self.diameter设置,然后用c.diameter = 10设置。
  • 命名diameter的类中的一种方法。此方法永远无法访问。您无法在实例上访问它,因为那里的 diameter属性 masks the方法。

在Python类中,方法仍然只是属性。c.area返回方法对象,只有c.area()实际调用方法。

因此,仅引用c.diameter实际上不会给您方法,它为您提供了实例上的属性,这只是一个整数对象。

您有两个选择:

  • 将方法重命名为set_diameter()
  • 使diameter属性A 属性对象。属性是的,就像属性一样,但是在实例触发方法上获取或设置属性。

后一个选项是" Pythonic"选项,经验丰富的Python开发人员将使用:

class Circle:
    def __init__(self, radius=1):
        self.radius = radius
    @property
    def diameter(self):
        return self.radius * 2
    @diameter.setter
    def diameter(self, value):
        self.radius = value / 2
    def area(self):
        return self.radius ** 2 * pi

@property/@diameter.setter装饰器对定义属性的Getter和Setter;每当您想要 read ( get (时,第一个def diameter被调用,属性的值,当您在 writater 时使用第二个值尝试分配一个新值( setter (:

>>> c = Circle(3)
>>> c.diameter
6
>>> c.diameter = 4
>>> c.radius
2.0
>>> c.diameter
4.0

请注意,我们从未在设置器中设置名为diameter的属性!相反,当您访问c.diameter进行阅读时,该值始终是计算的。

您还会注意到,当您将整数分配给diameter属性时,半径变为float值;这是因为/操作员即使对于整数输入也总是会产生浮点值。如果您始终必须具有整数。

,请使用//(地板部门(。

一种方法是与setter一起使用属性,以确保您更新内部数据:

类似的东西:

from math import pi

class Circle:
    def __init__(self, radius=1):
        self._radius = radius
        self._diameter = radius * 2
    @property
    def diameter(self):
        return self._diameter
    @diameter.setter
    def diameter(self, diameter):
        self._diameter = diameter
        self._radius = diameter / 2
    @property  
    def radius(self):
        return self._radius
    @radius.setter
    def radius(self, radius):
        self._radius = radius
        self._diameter = radius * 2
    def area(self):
        return self.radius ** 2 * pi
if __name__ == "__main__":
    c = Circle(3)
    print("c.radius:", c.radius)
    print("c.area():", c.area())
    c.radius = 4  # change radius
    print("c.radius:", c.radius)
    print("c.area():", c.area())
    c.diameter = 10  # change diameter
    print("c.diameter:", c.diameter)
    print("c.radius:", c.radius)

最新更新