gpt4 book ai didi

python - functool.partialmethod 和 functool.partial 的用法?

转载 作者:太空狗 更新时间:2023-10-30 02:40:58 33 4
gpt4 key购买 nike

考虑以下代码:

import functools
import inspect

class Foo:
def foo_fn(self, hello, world):
print(hello, world)

class FooWrapper:
def __init__(self, foo_class):
self._foo = foo_class()
for key, value in inspect.getmembers(self._foo):
if inspect.ismethod(value):
bound_fn = functools.partial(self.foo_wrapper_fn, self, value)
setattr(self._foo, key, bound_fn)

def foo_wrapper_fn(self_wrapper, self_foo, bound_method, hello, world):
bound_method(hello, world)

def make_foo(Foo):
wrapper = FooWrapper(Foo)
return wrapper._foo
a = make_foo(Foo)
a.foo_fn("hello", "world")
  1. 函数 foo_wrapper_fn() 参数(如 (self_wrapper, self_foo, bound_method, hello, world))的排序是如何形成的?而不是像这样:self_wrapper, bound_fn, self_foo, hello, world,因为 self_wrapperbound_fn 首先是部分绑定(bind)?

  2. 对象调用 functool.partial (而不是 functool.partialmethod) 的返回是否可以(a.foo_fn)?

  3. 如果我将其替换为 functools.partialmethod(self.foo_wrapper_fn, self, value) 为什么会出现此错误?

    TypeError: 'partialmethod' object is not callable

最佳答案

两个第一个参数都是同一个对象self.foo_wrapper_fn 绑定(bind)到 FooWrapper 实例(因为它是在 self 上查找的),然后你告诉部分传入 self 再次。所以实际上,签名只是一个双重混淆,您可以省略第二个参数,而不是直接传递第二个显式 self

请注意,您永远不会在任何地方传递 self._foo

顺序简单地设置为:

  1. 绑定(bind)方法,传入绑定(bind)的FooWrapper()实例。
  2. 无论您传递给 partial() 调用的位置参数是什么,所以 self ,值(value)。这又是 FooWrapper() 实例,以及绑定(bind)的 Foo 方法。
  3. 您在调用 partial() 对象时传入的任何其他参数。

必须在此处使用partial() 对象,而不是partialmethod(),因为您是在实例上设置属性。 partialmethod() 旨在用作描述符对象,例如类的一个属性。

这就是为什么您也会收到 TypeError 的原因; partialmethod() 从未被绑定(bind)。如果它被绑定(bind)(它的 __get__ method 被调用,传入要绑定(bind)到的实例),那么将返回一个适当的可调用对象。

参见 Python Descriptor Howto关于描述符如何工作(绑定(bind)方法是通过该协议(protocol)创建的,partialmethod 对象,以及 propertyclassmethodstaticmethod 对象,都建立在相同的原则上)。

因此您可以通过以下方式简化您的代码:

class FooWrapper:
def __init__(self, foo_class):
self._foo = foo_class()
for key, value in inspect.getmembers(self._foo):
if inspect.ismethod(value):
bound_fn = functools.partial(self.foo_wrapper_fn, value)
setattr(self._foo, key, bound_fn)

def foo_wrapper_fn(self, bound_method, hello, world):
bound_method(hello, world)

如果您必须访问原始 Foo() 实例,请在 bound_method 变量上使用 __self__ 属性。

关于python - functool.partialmethod 和 functool.partial 的用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41070352/

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