python - 子类装饰方法的类型不兼容 - python
问题描述
我收到一个错误
$ mypy python.py
python.py:34: error: Signature of "fn" incompatible with supertype "B"
python.py 在哪里
from typing import Callable, TypeVar, cast
T = TypeVar('T')
def dec(f: Callable[..., T]) -> T:
def p(self):
return getattr(self, '_' + f.__name__)
return cast(T, property(p))
class X:
pass
class Y(X):
pass
class A:
_fn = Y()
class B(A):
@dec
def fn(self) -> X:
return X()
class C(B):
@dec
def fn(self) -> Y:
return Y()
在这里,装饰器dec
意味着做两件事
- 将相应的方法提升为属性
- 将调用重定向到名称带有附加下划线的属性
我不明白为什么 mypy 无法确定 Y 从 X 继承。如果我替换-> Y
为-> X
,或者删除装饰器,则没有错误。
我已经用 mypy 0.630 和 Python 3.5.2、3.6.6 和 3.7.0 试过了
编辑正如评论中指出的A._fn
那样,最初发布的类型与C.fn
. 我已编辑A._fn
以消除此问题。错误没有改变。
编辑一些上下文 -A
是一个看起来更像的配置模式类
class A:
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, '_' + k, v)
我们希望用户像c = C(fn=Y()); c.fn # gives a Y
. 最初问题是A_.fn
作为返回的方法Y()
。更正此问题不会影响错误
编辑我已将此作为 mypy 错误https://github.com/python/mypy/issues/5836
解决方案
我认为您的意思是 dec 将返回 Callable 而不是 T。它应该是:
def dec(f: Callable[..., T]) -> Callable[..., T]:
def p(self):
return getattr(self, '_' + f.__name__)
return cast(Callable[..., T], property(p))
推荐阅读
- c++ - 在半透明窗口下查找像素的颜色
- typescript - 打字稿推断类型而不使用显式类型变量进行回调
- swift - swift - 如何确保最初定义特定属性的协议或类型?
- r - ifelse 按 r 中的列位置 - 列名未知
- reactjs - 单击按钮时从无状态组件内部调用函数
- python-3.x - 数据框融化并保留索引
- gitlab - 如何列出 GitLab Runner 的所有近期工作?
- web-scraping - 提高 getfollowers 函数的速度 - Instagram API - 作者:LevPasha
- java - 使用服务帐号在 GSuite 上列出云端硬盘文件时未授权
- c++ - Windows 上 libpng/1.6.34@bincrafters/stable 中的柯南冲突