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)