一位朋友昨天向我展示了下面在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