将类属性定义为实例变量的默认值是否惯用



一位朋友昨天向我展示了下面在Python中为实例变量提供默认值的技术。

Foo有自己的bar属性,在查找不存在的实例上的属性时,默认情况下会检索该属性。例如,下面的代码片段打印4✱.

class Foo:
bar = 4
def __init__(self):
pass
def get_bar(self):
return self.bar
def set_bar(self, bar):
self.bar = bar

print(Foo().get_bar())

起初,我很惊讶这种做法奏效了。我认为将foo_instance.get_bar转换/评估/定义为类Foo上的绑定方法并使foo_instance.get_bar()有意义的"回退到类上的定义"机制是特定于函数的,对于非函数来说会以某种方式失败。

事实并非如此。在__init__方法中,通过self.bar = 4设置了用于好像bar的上述代码prints

这种结构是惯用的吗?我能想到的唯一反对它的论点是,它破坏了结构上的平等,可能会隐藏调试时"逻辑上存在"的对象的属性,并且如果默认值是有状态的,可能会无意中改变全局状态。


✱getter和setter仅用于证明Foo.bar实际上是foo_instance.bar的默认值,不应被解释为支持在惯用Python中使用getter和getter。

我们可以让python为我们做艰苦的工作:

class Foo:
_bar = 4
@property
def bar(self):
print('getting _bar')
return self._bar
@bar.setter
def bar(self, value):
print('setting _bar')
self._bar = value
foo = Foo()
print(foo.bar)  # 4
foo.bar = 6
print(foo.bar)  # 6

最新更新