我有以下基本课程涉及一个圆圈。我的问题是,当我用c.diameter(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
答案 0 :(得分:0)
您有两件名为diameter
的东西:
self.diameter
中设置为__init__
,之后设置为c.diameter = 10
。diameter
的类的方法。永远不会访问此方法。您无法在实例上访问它,因为diameter
属性掩盖方法。在Python类中,方法仍然只是属性。 c.area
返回方法对象,只有c.area()
实际调用该方法。
因此,仅引用c.diameter
实际上不会为您提供方法,它会为您提供实例上的属性,它只是一个整数对象。
您有两种选择:
set_diameter()
,例如。diameter
属性设为property object。属性与属性一样使用,但在实例上获取或设置属性会触发要调用的方法。后一个选项是'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;每当您想要读取(获取)属性的值时,就会调用第一个def diameter
,而当写>>> c = Circle(3)
>>> c.diameter
6
>>> c.diameter = 4
>>> c.radius
2.0
>>> c.diameter
4.0
>当您尝试分配新值( setter )时调用:
diameter
请注意,我们从未在setter中设置名为c.diameter
的属性!相反,当您访问diameter
进行阅读时,始终会计算该值。
您还会注意到,当您为float
属性分配一个整数时,半径变为/
值;那是因为//
运算符总是产生一个浮点值,即使对于整数输入也是如此。如果你总是必须有一个整数,请使用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)
(分区)。
答案 1 :(得分:0)
一种方法是使用具有相应设置器的属性来确保更新内部数据:
这样的事情:
// Replace x with just under your max size.
const int kBufferSize = x * 1024 * 1024; // x MB