我经常看到这个:
None
为什么有些人使用默认值owner
作为descr.__get__(self, obj, type=None) --> value
参数?
甚至在Python docs:
中完成@echo off
setlocal
call :SplitFile < split.html > split-1.html
goto :EOF
:SplitFile
set "line="
set /P "line="
set /P "=%line%" < NUL
echo/
if "%line%" equ "</html>" (
rem Copy the rest of lines to part 2 and terminate
findstr "^" > split-2.html
exit /B
)
goto SplitFile
答案 0 :(得分:6)
因为可以很容易地从实例派生所有者,所以第二个参数是可选的。只有当没有实例从中派生所有者时,才需要所有者参数。
在引入描述符PEP 252 - Making Types Look More Like Classes:
的提案中对此进行了描述
__get__
:一个可以用一个或两个参数调用的函数 从对象中检索属性值。这也是 被称为&#34;绑定&#34;操作,因为它可能会返回一个 &#34;约束方法&#34;方法描述符的情况下的对象。该 第一个参数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>
此外,第二个参数可以很容易地从第一个参数派生;见证classmethod
仍然绑定到类,即使我们没有传递一个:
>>> classmethod(bar).__get__(foo)
<bound method type.bar of <class '__main__.Foo'>>
>>> classmethod(bar).__get__(foo)()
<class '__main__.Foo'>
首先论证的唯一原因是支持绑定到类,例如当没有实例绑定到时。类方法又来了;绑定到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'>>
答案 1 :(得分:3)
这是执行此操作的标准方法;我已经看到的所有Python内置描述符,包括函数,属性,静态方法等。我知道在描述符协议中没有所有情况,在没有所有者参数的情况下调用__get__
,但是如果你想要手动调用__get__
,不必通过所有者是有用的。所有者的论点通常不会做太多。
例如,you might want是一种更简洁的方法,可以为单个对象提供新方法。以下装饰器清除语法并让方法可以访问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()
现在a
有一个foo
方法。我们手动使用__get__
函数的foo
方法创建一个绑定方法对象,除了因为这个方法没有与一个类相关联,我们没有通过__get__
一堂课。几乎唯一的区别是,当您打印方法对象时,您会看到?.foo
而不是SomeClassName.foo
。
答案 2 :(得分:2)
因为这是描述符协议的指定方式:
descr.__get__(self, obj, type=None) --> value
cf https://docs.python.org/2/howto/descriptor.html#descriptor-protocol
type
参数允许访问在查找类而不是实例时查找描述符的类。由于您可以从实例中获取类,因此在实例上查找描述符时,它在某种程度上是多余的,因此它已被设置为可选的,以允许较不详细的desc.__get__(obj)
调用(而不是desc.__get__(obj, type(obj))
)。