在docs解释属性,据说:
Be sure to give the additional functions the same name as the original property (x in this case.)
即,getter、setter 和 deleter 方法必须具有相同的名称。
为什么?而且,Python 禁止方法重载,不是吗?
编辑: 为什么以下代码在 Python 2.6 中运行时会失败?
class Widget(object):
def __init__(self, thing):
self.thing = thing
print self.thing
@property
def thing(self):
return self._thing
@thing.setter
def set_thing(self, value):
self._thing = value
if __name__ == '__main__':
Widget('Some nonsense here')
它的输出是:
Traceback (most recent call last):
File "widget.py", line 16, in <module>
Widget('Some nonsense here')
File "widget.py", line 3, in __init__
self.thing = thing
AttributeError: can't set attribute
当 set_thing() 重命名为 thing() 时,代码工作正常。
最佳答案
Python 确实没有方法重载功能,但您是正确的,文档鼓励您以相同的方式命名 getter 和 setter,并演示它以启动。这是怎么回事?
诀窍在于了解方法装饰器在 Python 中的工作原理。每当你看到这样的东西时:
@foo
def bar():
frob()
quux()
Python 实际上在幕后做的是这样重写它:
def bar():
frob()
quux()
bar = foo(bar)
换句话说:定义一个函数 bar
,然后用调用 foo
的结果替换它 bar 函数。
虽然这一切都是真的,但就如何解析名称而言,求值顺序实际上与上述略有不同。暂时假装实际发生的事情看起来更接近于此可能更容易:
def __secret_internal_function_name__():
frob()
quux()
bar = foo(__secret_internal_function_name__)
为什么这很重要?让我们看看该文档链接中的 Python:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
让我们使用我们现在所知道的来重写它以了解 Python 实际在做什么:
class C(object):
def __init__(self):
self._x = None
def __secret_x_prop__(self):
"""I'm the 'x' property."""
return self._x
x = property(__secret_x_prop__)
def __secret_x_setter__(self, value):
self._x = value
x = x.setter(__secret_x_setter__)
def __secret_x_getter__(self):
del self._x
x = x.deleter(__secret_x_getter__)
现在,我们实际上可以看到发生了什么:我们不是在重载函数;而是在重载函数。我们正在逐渐构建一个引用其他函数的 property
对象。
还值得注意的是,根据您创建属性的方式,名称不需要匹配。具体来说,如果您使用 property
函数显式创建属性,就像在文档中的第一个示例中所做的那样,名称可以是您想要的任何名称;该示例将它们称为 getx
、setx
和 delx
,并且工作正常。在我假设的安全预防措施中,property.setter
、property.deleter
等do 要求传递的函数具有相同的名称,但它们在幕后做的事情与更明确的 property
示例相同。
关于python - 为什么 Python 属性需要同名的辅助函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12730191/