我有以下代码:
class Mixin:
def foo(self) -> int:
return 1
def add_mixin(cls):
class WithMixin(cls, Mixin):
__name__ = cls.__name__
__doc__ = cls.__doc__
return WithMixin
@add_mixin
class B:
def bar(self) -> int:
return 2
b = B()
print(b.foo())
print(b.bar())
我知道,在这个特殊的例子中,我可以只写B(Mixin)
而不使用装饰器,但实际上add_mixin
中有很多逻辑,它选择/定制Mixin
类(想想@dataclass
)
代码按照您期望的方式工作:打印1和2。然而,它使我的pyright
失明-我不再能够跳到bar
,因为pyright
不理解WithMixin
同时从Mixin
和B
继承
此外,mypy
会以另一种方式感到困惑:
mypy type_checking.py
type_checking.py:17: error: "B" has no attribute "foo"
Found 1 error in 1 file (checked 1 source file)
我正在注释一个现有库的核心,因此@overloads
列表或一些直接的魔法对我来说是好的-我只希望注释是正确的
我想在两件事上得到一些帮助:
add_mixin
(或者重写它以获得相同的效果),以便pyright
/mypy
正常工作李>typing
模块的实现(这很混乱!)以及类型检查器使用这些注释的方式。我读过reference for typing,也读过PEP 483和PEP 484,我想我对所有协方差/反方差/绑定类型的东西都有相当好的理解。然而,当有一件我以前没见过的复杂的事情发生时(比如这里),我感到完全迷失了方向。谷歌搜索通常会得到相同的参考风格或表面文章(或政治公众人物)李>我经历了多次失败的尝试,最后一次是:
from typing import *
class Mixin:
def foo(self) -> int:
return 1
_T1 = TypeVar("_T1")
class WithMixin(Type[_T1], Mixin):
...
def add_mixin(cls: Type[_T1]) -> WithMixin[_T1]:
return type(cls.__name__, (cls, Mixin), {})
@add_mixin
class B:
def bar(self) -> int:
return 2
b = B()
print(b.foo())
print(b.bar())
pyright
在type(cls.__name__, (cls, Mixin), {})
行感到困惑,而mypy
说不允许从Type[_T1]
继承(这是不允许的,但我认为类型检查器无论如何都可能会选择它)
目前没有回答
相关问题 更多 >
编程相关推荐