Thi*_*ves 3 python overloading properties
在解释属性的文档中,有人说:
请务必为其他函数指定与原始属性相同的名称(在本例中为x).
即,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')
Run Code Online (Sandbox Code Playgroud)
它的输出是:
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
Run Code Online (Sandbox Code Playgroud)
当set_thing()重命名为thing()时,代码工作正常.
Python确实没有使用方法重载的功能,但你是正确的,文档鼓励你以相同的方式命名getter和setter,并演示它来启动.这里发生了什么?
诀窍是了解方法装饰器如何在Python中工作.每当你看到这样的事情:
@foo
def bar():
frob()
quux()
Run Code Online (Sandbox Code Playgroud)
Python实际上做的是用这种方式重写它:
def bar():
frob()
quux()
bar = foo(bar)
Run Code Online (Sandbox Code Playgroud)
换句话说:定义一个函数bar,然后用调用foo bar函数的结果替换它.
虽然这一切都是正确的,但在涉及如何解析名称时,评估的顺序实际上与上述略有不同.你可能更容易假装实际发生的事情看起来更接近于此:
def __secret_internal_function_name__():
frob()
quux()
bar = foo(__secret_internal_function_name__)
Run Code Online (Sandbox Code Playgroud)
为什么这很重要?让我们看一下文档链接中的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
Run Code Online (Sandbox Code Playgroud)
让我们使用我们现在知道的内容重写它,以了解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__)
Run Code Online (Sandbox Code Playgroud)
现在,我们实际上可以看到发生了什么:我们没有超载功能; 我们正在逐步建立一个property引用其他功能的对象.
值得注意的是,根据您创建属性的方式,名称不需要匹配.具体来说,如果使用该property函数显式创建属性,就像在文档中的第一个示例中所做的那样,名称可以是您想要的任何名称; 这个例子有他们叫getx,setx和delx,它工作正常.在我认为是一种安全预防措施,property.setter,property.deleter等你需要传递的函数具有相同的名称,但他们正在做幕后的同样的事情更明确的property例子.
| 归档时间: |
|
| 查看次数: |
1448 次 |
| 最近记录: |