当前位置: 首页 > 面试题库 >

如何在实例方法中使用functools.singledispatch?

爱乐邦
2023-03-14
问题内容

Python
3.4添加了使用静态方法定义函数重载的功能。本质上是文档中的示例:

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)此功能使其与实例方法一起使用有任何建议吗?


问题答案:

更新: 从Python
3.8开始,functools.singledispatchmethod允许对方法,类方法,抽象方法和静态方法进行单次调度。

对于较旧的Python版本,请参见此答案的其余部分。

纵观来源的singledispatch,我们可以看到,装饰返回一个函数wrapper(),它选择的功能,从那些基于类型免费通话args[0]

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

…对于常规函数来说很好,但是对于实例方法来说用的很少,实例方法的第一个参数始终是self

但是,我们可以编写一个新的decorator
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()方法和注册的方法listself照常具有初始参数。

测试Patchwork课程:

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


 类似资料:
  • 本文向大家介绍在Vue中使用Echarts实例图的方法实例,包括了在Vue中使用Echarts实例图的方法实例的使用技巧和注意事项,需要的朋友参考一下 前言 由于在项目中需要对数据进行可视化处理,也就是用图表展示,众所周知echarts是非常强大的插件。但是新手猛的上手的话,可能会有点束手无策,所以这篇就是来写一点入门的内容,外加自己一点的小心得。 一、首先要在项目中下载echarts依赖 二、然

  • 我需要将xml转换为jpa实体。我已经使用jaxb获取了我的DTO,并使用mapstruct将dto转换为实体。但是,我需要从数据中提取一些数据,并将其设置为实体上的列表。我的映射器如下所示 我不知道如何在提取MetaData方法中访问我的实体特别。

  • 本文向大家介绍Android中使用AndroidTestCase的方法实例,包括了Android中使用AndroidTestCase的方法实例的使用技巧和注意事项,需要的朋友参考一下 Android 使用 AndroidTestCase 的步骤 1.新建一个类继承 AndroidTestCase 2.修改 AndroidManifest.xml 文件 在application 内部添加 appli

  • 我正在使用Saxon(如果需要,我可以使用Xalan)XSLT处理器进行一些转换。我想将下面对象的实例作为参数传递给XSLT模板。 所以我创建了这个对象。 在XSLT文件中,我将参数声明为: 现在我的问题是如何在XSLT内调用该对象的任何实例方法(即.getValue())?有可能吗?我知道我可以调用不同Java类的静态方法,但这并不完全是我想要的。 此外,是否可以在XSLT中填充Java对象,即

  • 本文向大家介绍使用Java8中的方法引用来引用实例方法,包括了使用Java8中的方法引用来引用实例方法的使用技巧和注意事项,需要的朋友参考一下 Java中的Lambda表达式使您可以将功能作为参数传递给方法。您也可以使用lambda表达式调用现有方法。 方法引用是简单,易于阅读的lambda表达式,可通过lambda表达式中的名称来调用/引用和现有方法。 语法 以下是在Java中引用实例方法的语法

  • 问题内容: 我是Java的初学者,我正在阅读有关如何通过键盘上的方法为变量赋值的主题。书中给出的程序如下: 我想问以下问题: 以下语句做了什么? 如果是的对象,那么什么是新的,并且上述声明右侧的声明做了什么? 为什么使用不同的方法将整数值放入intnumber和将float值放入floatnumber? 问题答案: 我建议您不要使用。专门为此目的设计并在Java 5中引入。请参阅以下链接以了解如何