简体   繁体   English

如何让“mypy”识别 function 的参数需要是特定基础 class 的子类?

[英]How do I get `mypy` to recognize that an argument of a function needs to be a subclass of a particular base 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认识到 function 的参数需要是特定基础 class 的子类? Consider the following:考虑以下:

# 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)

As shown in main.py , all subclasses of A implement a method f .main.py所示, A的所有子类都实现了一个方法f call_f in test.py takes an instance of one of the subclasses of A and calls this method. test.py中的call_f采用A的子类之一的实例并调用此方法。 An example of this is shown in the if __name__ == "__main__": section of test.py . test.pyif __name__ == "__main__":部分显示了一个示例。

One way to type hint the definition in test.py would be the following: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)

However, the disadvantage here is that I have to keep adding every new subclass of A into the function annotation of call_f which seems repetitive.但是,这里的缺点是我必须不断地将A的每个新子类添加到 call_f 的call_f注释中,这似乎是重复的。

Is there a better way to do this?有一个更好的方法吗?

I suppose that taking a stab at an answer isn't a bad idea at this point, since I have enough information from the comments.我想在这一点上尝试回答并不是一个坏主意,因为我从评论中获得了足够的信息。

You need to first enforce that f is implemented by subclasses of A .您需要首先强制fA的子类实现。 Otherwise, you could implement a subclass that doesn't implement f , and static typechecking would (rightfully) point out that there is nothing preventing that from occurring.否则,您可以实现一个不实现f的子类,并且 static 类型检查会(正确地)指出没有什么可以阻止这种情况的发生。 You could use Union[B, C] if you only wanted some subclasses to implement f , but you've already stated that this is undesirable for extensibility reasons.如果您只希望某些子类实现f ,则可以使用Union[B, C] ,但您已经说过出于可扩展性的原因,这是不可取的。

What you should do is have the function accept instances of the superclass A , and raise an error whenever f as defined in the superclass is invoked:您应该做的是让 function 接受超类A实例,并在调用超类中定义的f时引发错误:

class A:
  def f(self, x):
    raise NotImplementedError("A.f is not implemented, because A is an abstract class!") 

class B(A):
  def f(self, x):
    print(x)

class C(A):
  def f(self, x):
    print(x, "in C")

Then, call_f() would look like the following:然后, call_f()将如下所示:

def call_f(instance: A) -> None:
  instance.f("Hello")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 mypy,我如何键入 annotate 装饰器来装饰接受某事物子类的函数? - With mypy, how do I type annotate a decorator that decorates a function that accepts a subclass of something? 如何让 Mypy 识别 Callable 中类的协议成员身份? - How to get Mypy to recognize a class's protocol membership within a Callable? 你如何让 mypy 识别更新版本的 python? - How do you get mypy to recognize a newer version of python? Mypy:如何将类型作为函数参数并对该类型调用类方法 - Mypy: How to take a Type as function argument and invoke a class method on that type 在 python 类型提示中,如何让参数接受基类的任何子类? - In python type-hinting, how can I make an argument accept any subclass of a base class? 如何在python中为函数的特定参数指定范围? - How do I specify the range for a particular argument of a function in python? 如何让 Mypy 识别不可为 null 的 ORM 属性? - How do I make Mypy recognize non-nullable ORM attributes? 如何让mypy识别或忽略动态导入的类型? - How can I get mypy to either recognize or ignore dynamically imported types? 如何获得 MyPy 的正则表达式模式类型 - How do I get a regex pattern type for MyPy 使用 mypy 确保 Python class 中的两个字段是给定基础 class 的相同子类 - Ensure two fields in a Python class are the same subclass of a given base class using mypy
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM