我如何让 mypy 识别函数的参数需要是特定基数 class 的子 class?
How do I get mypy to recognize that an argument of a function needs to be a subclass of a particular base class?
如何让 mypy
识别函数的参数需要是特定基 class 的子class?考虑以下因素:
# main.py
class A: ...
class B(A):
def f(self, x):
print(x)
class C(A):
def f(self, x):
print(x, "in C")
# test.py
def call_f(instance):
instance.f("Hello")
if __name__=="__main__":
from main import B, C
b = B()
call_f(b)
c = C()
call_f(c)
如 main.py
所示,A
的所有子 class 实现方法 f
。 test.py
中的 call_f
获取 A
的子 class 之一的实例并调用此方法。 test.py
.
的 if __name__ == "__main__":
部分显示了这方面的示例
在 test.py
中键入提示定义的一种方法如下:
# test_typed.py
from typing import Union
from main import B, C
def call_f(instance: Union[B, C]) -> None:
instance.f("Hello")
if __name__=="__main__":
from main import B, C
b = B()
call_f(b)
c = C()
call_f(c)
然而,这里的缺点是我必须不断将A
的每个新子class添加到call_f
的函数注释中,这似乎是重复的。
有更好的方法吗?
我想现在尝试一下答案并不是个坏主意,因为我从评论中获得了足够的信息。
您需要首先强制执行 f
由 A
的子类实现。否则,您可以实现一个不实现 f
的子类,并且静态类型检查会(正确地)指出没有什么可以阻止这种情况的发生。如果您只希望某些子类实现 f
,您可以使用 Union[B, C]
,但您已经声明出于可扩展性原因,这是不可取的。
您应该做的是让函数接受超类 A
的实例,并在调用超类中定义的 f
时引发错误:
from abc import ABC, abstractmethod
class A(ABC):
@abstractmethod
def f(self, x):
raise NotImplementedError("This method should be defined in subclasses of A.")
class B(A):
def f(self, x):
print(x)
class C(A):
def f(self, x):
print(x, "in C")
那么,call_f()
将如下所示:
def call_f(instance: A) -> None:
instance.f("Hello")
如何让 mypy
识别函数的参数需要是特定基 class 的子class?考虑以下因素:
# main.py
class A: ...
class B(A):
def f(self, x):
print(x)
class C(A):
def f(self, x):
print(x, "in C")
# test.py
def call_f(instance):
instance.f("Hello")
if __name__=="__main__":
from main import B, C
b = B()
call_f(b)
c = C()
call_f(c)
如 main.py
所示,A
的所有子 class 实现方法 f
。 test.py
中的 call_f
获取 A
的子 class 之一的实例并调用此方法。 test.py
.
if __name__ == "__main__":
部分显示了这方面的示例
在 test.py
中键入提示定义的一种方法如下:
# test_typed.py
from typing import Union
from main import B, C
def call_f(instance: Union[B, C]) -> None:
instance.f("Hello")
if __name__=="__main__":
from main import B, C
b = B()
call_f(b)
c = C()
call_f(c)
然而,这里的缺点是我必须不断将A
的每个新子class添加到call_f
的函数注释中,这似乎是重复的。
有更好的方法吗?
我想现在尝试一下答案并不是个坏主意,因为我从评论中获得了足够的信息。
您需要首先强制执行 f
由 A
的子类实现。否则,您可以实现一个不实现 f
的子类,并且静态类型检查会(正确地)指出没有什么可以阻止这种情况的发生。如果您只希望某些子类实现 f
,您可以使用 Union[B, C]
,但您已经声明出于可扩展性原因,这是不可取的。
您应该做的是让函数接受超类 A
的实例,并在调用超类中定义的 f
时引发错误:
from abc import ABC, abstractmethod
class A(ABC):
@abstractmethod
def f(self, x):
raise NotImplementedError("This method should be defined in subclasses of A.")
class B(A):
def f(self, x):
print(x)
class C(A):
def f(self, x):
print(x, "in C")
那么,call_f()
将如下所示:
def call_f(instance: A) -> None:
instance.f("Hello")