Mar*_*nen 10 python descriptor python-3.x python-descriptors
我经常看到这个:
def __get__(self, instance, owner=None):
Run Code Online (Sandbox Code Playgroud)
为什么有些人使用的默认值None的的owner参数?
这甚至可以在Python文档中完成:
descr.__get__(self, obj, type=None) --> value
Run Code Online (Sandbox Code Playgroud)
因为所有者可以很容易地从实例派生,所以第二个参数是可选的.只有当没有实例从中派生所有者时,才需要所有者参数.
引入描述符的提议中描述了这一点,PEP 252 - 使类型看起来更类似于类:
__get__:一个可调用一个或两个参数的函数,用于从对象中检索属性值.这也称为"绑定"操作,因为在方法描述符的情况下它可以返回"绑定方法"对象.第一个参数X是必须从中检索属性或必须绑定到的对象. 当X是None,可选的第二个参数,T应该是元对象,绑定操作可能返回一个限制为实例的未绑定方法T.
(大胆强调我的).
从第一天开始,绑定意味着仅适用于实例,类型是可选的.例如,方法不需要它,因为它们可以单独绑定到实例:
>>> class Foo: pass
...
>>> def bar(self): return self
...
>>> foo = Foo()
>>> foo.bar = bar.__get__(foo) # look ma! no class!
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0x10a0c2710>>
>>> foo.bar()
<__main__.Foo object at 0x10a0c2710>
Run Code Online (Sandbox Code Playgroud)
此外,第二个参数可以很容易地从第一个参数中导出 ; 见证classmethod仍然绑定到班级,即使我们没有通过一个:
>>> classmethod(bar).__get__(foo)
<bound method type.bar of <class '__main__.Foo'>>
>>> classmethod(bar).__get__(foo)()
<class '__main__.Foo'>
Run Code Online (Sandbox Code Playgroud)
首先,参数的唯一原因是支持绑定到类,例如,当没有要绑定的实例时.类方法又来了; 绑定到None实例将不起作用,它只有在我们实际传入类时才有效:
>>> classmethod(bar).__get__(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __get__(None, None) is invalid
>>> classmethod(bar).__get__(None, Foo)
<bound method type.bar of <class '__main__.Foo'>>
Run Code Online (Sandbox Code Playgroud)
这是执行此操作的标准方法;我见过的所有 Python 内置描述符都这样做,包括函数、属性、静态方法等。我知道在描述符协议中没有任何情况下__get__会在没有 owner 参数的情况下调用,但是如果你想__get__手动调用,它可以不必通过所有者很有用。所有者参数通常没有多大作用。
例如,您可能需要一种更简洁的方式来为单个对象提供新方法。以下装饰器清理了语法并让方法可以访问self:
def method_of(instance):
def method_adder(function):
setattr(instance, function.__name__, function.__get__(instance))
return function
return method_adder
@method_of(a)
def foo(self, arg1, arg2):
stuff()
Run Code Online (Sandbox Code Playgroud)
现在a有个foo方法。我们手动使用函数的__get__方法foo来创建绑定方法对象,就像其他任何方法一样,除了由于此方法不与类关联,因此我们没有传递__get__类。几乎唯一的区别是,当您打印方法对象时,您看到的?.foo是SomeClassName.foo.
| 归档时间: |
|
| 查看次数: |
458 次 |
| 最近记录: |