4 回答
TA贡献1856条经验 获得超11个赞
如果你这样做:
@color.setter
def color(self, x):
self.color = x
然后这个 setter 会反复调用自己。obj1.color = 'blue'和之间没有区别self.color = x,它们都做同样的事情,就是调用 setter def color。因此,随着 setter 递归调用自身,您将拥有一个无限的递归循环,最终会使您的程序崩溃。
为此,您需要将值实际存储在其他一些属性上。使用“ _color”作为它的名字只是一个相当明显的解决方案。
请注意,如果您的 setter/getter不做任何事情,那么在 Python 中使用这种 setter/getter 是不受欢迎的。您可以完全删除它们,并且只是简单地设置self.color = 'blue'为与您的 setter/getter 对当前具有的完全相同的效果。如果他们做了一些额外的处理,你应该只使用 setter/getter。由于普通属性和 setter/getter 的语法是相同的,如果需要,您甚至可以在以后安全地过渡到使用 setter/getter(与 Java 相比,setter/getterfoo.setBar(...)是相同foo.bar = ...且以后不能透明地替换)。
TA贡献1865条经验 获得超7个赞
我想令人困惑的部分在__init__. self.color = colorin__init__实际上是在调用你的 setter,它会创建名为 的私有变量_color。setter 和 getter 作为这个 private 的包装器工作,_color允许您做一些额外的事情,而不是直接访问原始变量。
我不知道这是否是调用 setter in 的常见做法__init__,但我更喜欢直接在 in 中定义包装的私有变量__init__。对我来说,它看起来更简单
class FavoriteColor:
def __init__(self, color):
self._color = color
TA贡献1886条经验 获得超2个赞
像大多数编程语言一样,Python 约定用下划线“_”定义类的私有变量,因此通过命名“_color”我们意味着创建一个私有属性“color”。
对于您的第二个问题,您应该为刚刚定义的属性定义 getter setter 属性,根据属性装饰器的规则,我们必须定义与目标属性相同名称的 getter setter 方法以及 @property装饰师。
希望能帮助到你
class FavoriteColor:
def __init__(self, color):
self._color = color
# a getter funcion
@property
def color(self):
return self._color
# a setter function
@color.setter
def color(self, value):
self._color = value
TA贡献1719条经验 获得超6个赞
Python 变量和函数共享相同的命名空间。因此self.color只能引用 getter/setter 方法或属性本身。一个常见的约定是在内部属性名称中添加下划线,以避免这种命名冲突,这也通常传达了它是私有属性的概念。
这应该已经解释了您的其他问题。如果您有一个名为的方法self.color,并且它包含将自身替换为值的代码,那么您当然不能再使用self.color该方法再次引用该方法。
让我们再看一个更简单的例子。
>>> class X:
... def color (self, value):
... self.color = value
第一次调用该函数时——比如说,xinstance.color("red")它会将实例设置color为"red". 那么你就不能再调用xinstance.color()了,因为它现在是一个字符串,而不是一个函数。
添加@property装饰器会稍微改变这一点,因为 nowself.color = value会导致color调用自身,这会导致它调用自身,这会导致它再次调用自身,等等。
添加回答
举报