如何使用可调用对象作为方法定义? [英] How do I use a callable object as a method definition?
问题描述
我知道可以定义一个函数并将其用作方法:
I know it's possible to define a function and use it as a method:
def method(*args, **kwargs):
print "%r %r" % (args, kwargs)
class Test(object):
method1 = method
t = Test()
t.method1() # (<__main__.Test object at 0x10705a4d0>,) {}
我想对可调用对象做同样的事情,就像这样:
I'd like to do the same thing with callable objects, like this:
class Method(object):
__call__ = method
class Test(object):
method1 = Method()
但是,当我这样做时,Method.__call__
的 self
参数是方法本身(这是正常的),但是 self
> Test
实例的参数丢失.
However, when I do this, the self
argument of Method.__call__
is the method itself (which is normal), but the self
argument of the Test
instance is lost.
t = Test()
t.method1() # (<__main__.Method object at 0x10703f110>,) {}
是否可以将 self
参数作为第二个参数传递给 Method.__call__
?
Is it possible to have the self
argument passed as the second argument to Method.__call__
?
推荐答案
通过将该函数 method
包装在一个类中,您可以有效地阻止将对象绑定到函数从而创建方法的机制.它的工作方式是常规 python 函数是 描述符.
By wrapping that function method
in a class you are effectively preventing the mechanism that binds an object to a function and thus creates a method. The way this works is that regular python functions are descriptors.
总结文档:当您编写以下代码时:
To summarize the docs: When you write the following code:
some_instance.some_function()
some_function
的 __get__
方法以 some_instance
作为第一个参数被调用.__get__
方法然后返回一个绑定的方法对象,该对象记住该实例.稍后,当绑定方法对象的 __call__
方法被调用时,它会将保存的实例作为第一个参数传递.
The some_function
s __get__
method is called with some_instance
as the first parameter. The __get__
method then returns a bound method object, that remembers the instance. Later, when the bound method object's __call__
method is called, it passes the saved instance as a first parameter.
我们可以像这样重新实现该行为:
We can reimplement that behaviour like this:
def method(*args, **kwargs):
print("%r %r" % (args, kwargs))
class BoundMethod(object):
# the bound method remembers the instance and the function
def __init__(self, instance, function):
self.instance = instance
self.function = function
# when the bound method is called, it passes the instance
def __call__(self, *args, **kwargs):
return self.function(self.instance, *args, **kwargs)
class Method(object):
# the __get__ method assembles a bound method consisting of the
# instance it was called from and the function
def __get__(self, instance, cls):
return BoundMethod(instance, method)
class Test(object):
method1 = Method()
t = Test()
t.method1() # (<__main__.Test object at 0x7f94d8c3aad0>,) {}
在您的情况下 Method
不是描述符.因此,当在内部请求 __call__
属性(它是一个函数)时,它会绑定到包含类 (Method
) 的对象.
In your case Method
is not a descriptor. So, when internally the __call__
property (which is a function) is requested it is bound to an object of the containing class (Method
).
我不确定这是否有用,因为这个例子只是幕后发生的事情的简化版本.
I am not sure if this is useful, as this example is just a simplified version of what happens under the hood anyway.
注意:在这个例子中:
class C:
def function(self): pass
print(C.function)
print(C().function)
第一个打印告诉我们,未绑定方法的字面称为
而绑定方法称为
The first print shows us, that an unbound method literally is called <unbound method C.function>
while a bound method is called <bound method C.function of ...>
.
然而,在 python3 中,第一个打印向我们展示了未绑定的方法只是我们在类中定义的未更改的函数.
In python3 however the first print shows us that unbound methods are just the unchanged functions we defined in the class.
这篇关于如何使用可调用对象作为方法定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!