【发布时间】:2019-12-06 10:30:35
【问题描述】:
我想将我的函数放在某个注册表中,并根据提供的一些参数(多重调度的一个版本)选择所需的函数。
这是示例代码:
method_registry = {}
def accepts(cls):
""" A decorator that registers functions on some registry"""
def register(func):
method_registry[cls] = func
return func
return register
def handle(obj):
""" Pick a function that corresponds to the provided object class and run it """
handler = method_registry[obj.__class__]
handler(obj)
现在,我打算如何使用它:
class Dog:
def bark(self):
print('bark')
class Cat:
def meow(self):
print('meow')
@accepts(Dog)
def handle_dog(obj):
obj.bark()
@accepts(Cat)
def handle_cat(obj):
obj.meow()
# Here comes multiple dispatch
handle(Dog())
handle(Cat())
现在,一切正常,但是当我尝试为 mypy 注释我的函数时,我必须输入 Cat 和 Dog 两次:
@accepts(Dog)
def handle_dog(obj: Dog) -> None:
obj.bark()
@accepts(Cat)
def handle_cat(obj: Cat) -> None:
obj.meow()
所以,我猜一定有一种方法可以创建一个泛型类型,它可以为我注释我的obj-s 而无需复制代码。
但我似乎无法完成这项工作。
我的尝试是这样的:
V = TypeVar('V')
def accepts(cls: Type[V]) -> Callable[[Callable], Callable[[V], None]]:
def register(func: Callable) -> Callable[[V], None]:
method_registry[cls] = func
return func
return register
但这无济于事:
@accepts(Dog)
def handle_dog(obj) -> None:
reveal_type(obj) # Revealed type is 'Any'
obj.bark()
有没有办法让它工作?
【问题讨论】:
-
AFAIK mypy 无法为您添加注释,因为它是静态代码分析器,应该手动完成