python - functools.partialmethod 和 classmethod 的组合

标签 python python-3.x python-3.5 class-method functools

我想在类方法上使用 functools.partialmethod。然而,我发现的行为并不是我所期望的(并且喜欢)。 这是一个例子:

class A(object):
    @classmethod
    def h(cls, x, y):
        print(cls, x, y)

class B(A):
    h = functools.partialmethod(A.h, "fixed")

当我这样做

>>> b = B()
>>> b.h(3)

我得到一个错误:

...
TypeError: h() takes 3 positional arguments but 4 were given

这符合

>>> b.h()
<class '__main__.A'> <__main__.B object at 0x1034739e8> fixed

但是,我希望(并希望)有以下行为:

>>> b.h(4)
<class '__main__.B'> fixed 4

我认为 functools.partialmethodB.h 视为普通实例方法,并自动将实际实例作为第一个参数传递。 但是这种行为使得 functools.partialmethod 无法卡住继承类的类方法中的参数。

最佳答案

无需过多赘述,partial 对象与@classmethod 用于创建类实例的描述符协议(protocol)不能很好地融合。简单的解决方法是以通常的方式定义重写的方法:

class B(A):
    @classmethod
    def h(cls, y):
        return A.h("fixed", y)

可能可以通过调用 partial 来做你想做的事,但我找不到它。以下是我的一些尝试,以及它们失败的原因。

A.h 调用函数对象的 __get__ 方法,返回第一个参数已经绑定(bind)到调用类的函数。 partial 然后将该函数应用到 "fixed",但是随后生成的可调用 still 有一个 __get__ 方法尝试将调用类插入到结果调用中。您可以尝试通过将 h 定义为实际的 static 方法来解决这个问题:

class B(A):
    h = staticmethod(partial(A.h, "fixed"))

>>> B.h(4)
<class '__main__.A'> fixed 4

但是如您所见,您在调用 partial 时已经卡住了类参数。另一种尝试是通过直接访问参数来避免描述符协议(protocol):

class B(A):
    h = staticmethod(partial(A.__dict__["h"], "fixed"))

但是 classmethod 对象实际上是不可调用的;只有它们的 __get__ 方法的返回值是,所以调用 partial 失败。

关于python - functools.partialmethod 和 classmethod 的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39332671/

相关文章:

python - 在 pandas 中进行透视后重置索引而无需多个 header

python - numpy 从线性函数生成数据

python - CSV 以字节形式返回而不是字符串 Python

python - 如何从 Python 3.5 升级到 3.6?

ffmpeg - 无法打开文件 v_YoYo_g07_c04.jpeg av_interleaved_write_frame() : Input/output error

python - Python 3.5 中的类型提示是什么?

python - 两个 python 对象都大于或小于彼此

Python: pip 在根目录下安装子包

二进制数的Python打印格式

python - 如何使用虚拟环境在ansible playbook中运行python脚本?