【发布时间】:2023-01-27 02:21:53
【问题描述】:
对于我的代码,我有一个聚合类,它需要为基类 BaseC 的每个子类定义一个验证方法,在本例中 InheritC 继承自 BaseC。
然后通过注册方法将验证方法传递到聚合类中。
请参阅以下简单示例
from typing import Callable
class BaseC:
def __init__(self) -> None:
pass
class InheritC(BaseC):
def __init__(self) -> None:
super().__init__()
@classmethod
def validate(cls, c:'InheritC') ->bool:
return False
class AggrC:
def register_validate_fn(self, fn: Callable[[BaseC], bool])-> None:
self.validate_fn = fn
ac = AggrC()
ic = InheritC()
ac.validate_fn(ic.fn)
我在注册函数的参数上添加了类型提示,它是一个 Callable 对象 Callable[[BaseC], bool],因为可能会有其他几种验证方法,这些方法是为从 BaseC 继承的每个类定义的。
但是,pylance 似乎无法识别 Callable 类型提示中的这种多态性,并发出警告(我设置我的 VScode 以对其进行类型检查)说
Argument of type "(c: InheritC) -> bool" cannot be assigned to parameter "fn" of type "(BaseC) -> bool" in function "register_fn"
Type "(c: InheritC) -> bool" cannot be assigned to type "(BaseC) -> bool"
Parameter 1: type "BaseC" cannot be assigned to type "InheritC"
"BaseC" is incompatible with "InheritC" Pylance(reportGeneralTypeIssues)
我看不出我在设计中哪里犯了错误,我不想简单地忽略警告。
谁能解释为什么这是无效的? 或者它只是来自 pylance 的错误
我正在使用 python 版本 3.8.13 进行开发。
【问题讨论】:
-
没有检查自己,我怀疑问题是
InheritC::validate不兼容,因为它不仅采用一个BaseC-compatible 参数,它还采用类cls参数。我相信一个独立的函数,称为validate,它只要将BaseC-compatible 对象作为参数,就可以了。 -
我没有检查过,但您可能还想尝试删除
@classmethod装饰器,并将该方法声明为def validate(self: 'InheritC'): return False,然后传递那到register_validate_fn。我假设这些例子是从一个真实的应用程序中剥离出来的;你没有在调用validate_fn之前调用register_validate_fn,但我认为你是故意的。 -
很抱歉继续回复,但是...示例代码中还有另一个错误:
ic.fn未定义。我会开始用我的东西来回答思考该样本应该读起来像。 -
我对方法参数的理解是错误的——问题更微妙,我会写一个完整的答案,因为这是一个相当抽象的问题。
标签: python type-hinting typechecking pylance