如何使用可调用对象作为方法定义? [英] How do I use a callable object as a method definition?

查看:33
本文介绍了如何使用可调用对象作为方法定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道可以定义一个函数并将其用作方法:

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_functions __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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆