gpt4 book ai didi

python - 如何将 functools.singledispatch 与实例方法一起使用?

转载 作者:IT老高 更新时间:2023-10-28 21:44:37 26 4
gpt4 key购买 nike

Python 3.4 added使用静态方法定义函数重载的能力。这基本上是文档中的示例:

from functools import singledispatch


class TestClass(object):
@singledispatch
def test_method(arg, verbose=False):
if verbose:
print("Let me just say,", end=" ")

print(arg)

@test_method.register(int)
def _(arg):
print("Strength in numbers, eh?", end=" ")
print(arg)

@test_method.register(list)
def _(arg):
print("Enumerate this:")

for i, elem in enumerate(arg):
print(i, elem)

if __name__ == '__main__':
TestClass.test_method(55555)
TestClass.test_method([33, 22, 11])

在其最纯粹的形式中,singledispatch 实现依赖于第一个参数来识别类型,因此很难将此功能扩展到实例方法。

是否有人对如何使用(或 jerry-rig)此功能以使其与实例方法一起使用有任何建议?

最佳答案

Update: As of Python 3.8, functools.singledispatchmethod allows single dispatch on methods, classmethods, abstractmethods, and staticmethods.

For older Python versions, see the rest of this answer.

source对于singledispatch,我们可以看到装饰器返回一个函数wrapper(),它根据args[0的类型从注册的函数中选择一个函数来调用] ...

    def wrapper(*args, **kw):
return dispatch(args[0].__class__)(*args, **kw)

...对于常规函数来说很好,但对于实例方法用处不大,它的第一个参数总是self

然而,我们可以编写一个新的装饰器 methdispatch,它依赖 singledispatch 来完成繁重的工作,而是返回一个包装函数来选择要注册的函数根据args[1]的类型调用:

from functools import singledispatch, update_wrapper

def methdispatch(func):
dispatcher = singledispatch(func)
def wrapper(*args, **kw):
return dispatcher.dispatch(args[1].__class__)(*args, **kw)
wrapper.register = dispatcher.register
update_wrapper(wrapper, func)
return wrapper

这是一个使用装饰器的简单示例:

class Patchwork(object):

def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)

@methdispatch
def get(self, arg):
return getattr(self, arg, None)

@get.register(list)
def _(self, arg):
return [self.get(x) for x in arg]

请注意,装饰的 get() 方法和注册到 list 的方法都像往常一样具有初始 self 参数。

测试 Patchwork 类:

>>> pw = Patchwork(a=1, b=2, c=3)
>>> pw.get("b")
2
>>> pw.get(["a", "c"])
[1, 3]

关于python - 如何将 functools.singledispatch 与实例方法一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24601722/

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