gpt4 book ai didi

python - 如何使用可调用对象作为方法定义?

转载 作者:行者123 更新时间:2023-11-28 20:31:39 25 4
gpt4 key购买 nike

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

def method(*args, **kwargs):
print "%r %r" % (args, kwargs)

class Test(object):
method1 = method

t = Test()
t.method1() # (<__main__.Test object at 0x10705a4d0>,) {}

我想对可调用对象做同样的事情,像这样:

class Method(object):
__call__ = method

class Test(object):
method1 = Method()

但是,当我这样做时,Method.__call__self 参数是方法本身(这是正常的),但是 self Test 实例的参数丢失。

t = Test()
t.method1() # (<__main__.Method object at 0x10703f110>,) {}

是否可以将 self 参数作为第二个参数传递给 Method.__call__

最佳答案

通过包装该函数 method在一个类中,您有效地阻止了将对象绑定(bind)到函数并因此创建方法的机制。它的工作方式是常规 python 函数是 descriptors .

总结文档:当您编写以下代码时:

some_instance.some_function()

some_function s __get__使用 some_instance 调用方法作为第一个参数。 __get__方法然后返回一个绑定(bind)方法对象,它会记住实例。后来,当绑定(bind)方法对象的 __call__方法被调用时,它将保存的实例作为第一个参数传递。

我们可以像这样重新实现该行为:

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__属性(它是一个函数)被请求绑定(bind)到包含类(Method)的对象。

我不确定这是否有用,因为这个例子只是底层发生的事情的简化版本。

注意:在这个例子中:

class C:
def function(self): pass

print(C.function)
print(C().function)

第一个打印向我们展示了一个未绑定(bind)方法的字面意思是 <unbound method C.function>而绑定(bind)方法称为 <bound method C.function of ...> .

但是在 python3 中,第一个打印向我们展示了未绑定(bind)的方法只是我们在类中定义的未更改的函数。

关于python - 如何使用可调用对象作为方法定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54044943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com