类型为的singledispatchmethod

2024-09-28 22:28:51 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python3.8中,创建了一个用于创建多态函数的新装饰器@singledispatchmethod,它根据提供的类型提示将Python重定向到方法的正确实现

但是,我似乎无法使用输入模块中的复杂类型,请告诉我我的示例有什么问题

from typing import List
from functools import singledispatchmethod
class test:
    @singledispatchmethod
    def a(self, a):
        return NotImplemented

    @a.register
    def _(self, a : str):
        print(type(a))
    
    # Uncomment to run the example
    # @a.register
    # def _(self, a: List[str]):
    #    print(type(a))

    def b(self, b: List[str]):
        print(type(b))

test().a(["A"])
test().b(["A"])

若第二个下划线函数的注释未注释,则a函数会发生以下错误,即使b函数不会发生此错误:

TypeError: Invalid annotation for 'a'. typing.List[str] is not a class.

我做错了什么


Tags: 函数fromtestimportselfregistertyping类型
1条回答
网友
1楼 · 发布于 2024-09-28 22:28:51

从评论中,听起来可能有potential changessingledispatchmethod,但是如果您对允许分派和键入都起作用的可用解决方案感兴趣,这里有一些选项:

  1. 用实际类list注册重载,然后为重载(see related answer)提供更具体的类型提示
  2. 使用像^{}这样的项目来处理更多参数化的typing类型

选项1:使用list注册并添加更具体的重载类型提示

from functools import singledispatchmethod
from typing import List, overload


class test:
    @singledispatchmethod
    def overloaded_a(self, a):
        return NotImplemented

    @overloaded_a.register
    def _(self, a: str):
        print(type(a))

    @overloaded_a.register
    def _from_list(self, a: list):
        print(type(a))

    @overload
    def a(self, a: str): ...

    @overload
    def a(self, a: List[str]): ...

    def a(self, *args, **kwargs):
        return self.overloaded_a(*args, **kwargs)

    def b(self, b: List[str]):
        print(type(b))


test().a(["A"])
test().b(["A"])
test().a("this")
# test().a([34])  # mypy error: List item 0 has incompatible type "int"; expected "str"
# test().b("this")  # mypy error: Argument 1 to "b" of "test" has incompatible type "str"; expected "List[str]"

选项2:使用multimethod

from typing import List

from multimethod import multimethod as singledispatchmethod


class test:
    @singledispatchmethod
    def a(self, a):
        return NotImplemented

    @a.register
    def _(self, a: str):
        print("str")
        print(type(a))

    @a.register
    def _from_str_list(self, a: List[str]):
        print("str list")
        print(type(a))

    @a.register
    def _from_int_list(self, a: List[int]):
        print("int list")
        print(type(a))

    def b(self, b: List[str]):
        print(type(b))


test().a(["A"])
test().a([3])
test().b(["A"])
# test().b(3) # mypy error: Argument 1 to "b" of "test" has incompatible type "int"; expected "List[str]"

相关问题 更多 >