是否可以在 Python 中将 functools.singledispatch 与复合/嵌套/容器类型一起使用?

如何解决是否可以在 Python 中将 functools.singledispatch 与复合/嵌套/容器类型一起使用?

不知能否实现以下, 如果是这样,不需要太多额外的代码

from __future__ import annotations
from functools import singledispatch

@singledispatch
def somefunc(value):
    print(f"Type {type(value).__qualname__!r} "
          f"is not registered for dispatch.")

@somefunc.register
def _(value: list[int]):
    print(f"dispatched type list[int]!")

@somefunc.register
def _(value: list[str]):
    print(f"dispatched type list[str]!")

somefunc('123')
somefunc([123])
somefunc(list('123'))

并得到输出

Type 'str' is not registered for dispatch.
dispatched type list[int]!
dispatched type list[str]!

然而,使用 python 3.9.6 运行此代码段会导致在 functools.py 的第 742 行出现错误

TypeError: issubclass() argument 2 cannot be 
a parameterized generic

由于 singledispatch 确实适用于用户定义的类,使这项工作的一种方法是对传递的列表中的元素进行类型检查,将传递的列表包装到一个表示例如的类中list[str] 并让分派的函数以新实例作为参数再次调用自身:

from __future__ import annotations
from functools import singledispatch


class listofStrs(list):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)


class listofInts(list):
    def __init__(self,**kwargs)


@singledispatch
def somefunc(value):
    print(f"Type {type(value).__qualname__!r} "
          f"is not registered for dispatch.")


@somefunc.register
def _(value: list):
    if value and all(isinstance(subval,int) 
                     for subval in value):
        somefunc(listofInts(value))

    elif value and all(isinstance(subval,str) 
                       for subval in value):
        somefunc(listofStrs(value))

    else:
        print(
            f"dispatched a list whose elements ",f"are not all of a registered type."
            )


@somefunc.register
def _(value: listofStrs):
    print(f"dispatched type 'list[str]'!")


@somefunc.register
def _(value: listofInts):
    print(f"dispatched type 'list[int]'!")


somefunc('123')
somefunc([1,2,3])
somefunc(list('123'))
somefunc([{1},{2},{3}])

正如预期的那样,结果:

Type 'str' is not registered for dispatch.
dispatched type 'list[int]'!
dispatched type 'list[str]'!
dispatched a list whose elements are 
 not all of a registered type.

然而,除了增加可扩展性之外,首先使用 singledispatch 的原因之一是为了规避冗长的类型检查,有些人认为这是一种反模式。当然,对于这个解决方案,您需要定义乱扔代码的包装类(可能有更好的方法来实现这一点,我目前没有看到,但第一点仍然存在)。

有理由在这里避免对“list”进行一次类型检查,但这仅通过一个 if/else 子句就降低了复杂性。

所以我实际上不会使用最后一种情况。

有谁知道如何像使用非复合类型一样优雅地获得这种行为?

我想这可以在 3.10 中使用模式匹配优雅地完成。所以,如果目前不可行,也许我应该等待它的推出和成熟?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?