【问题标题】:Python typing from List of classes从类列表中键入 Python
【发布时间】:2021-03-18 11:51:51
【问题描述】:

如何为类列表进行 python 输入。

假设我有以下课程。

from dataclasses import dataclass

@dataclass
class A:
    name: str

@dataclass
class B:
   age: int

#...
CLASSES = [A, B]  #... more classes in list

现在我定义一个函数来实例化以下任何一个类

def func(resource: Union[*CLASSES], value: Union[str, int]):
    return resource(value)

但是类型提示在这里无效。 如何从 List 中进行类型提示?

【问题讨论】:

  • 你所说的“类型转换”到底是什么意思?请具体。请注意,“类型转换”并不是真正适用于 python 的术语,尽管它被非正式地用来表示“类型转换”。
  • 如果您有 10 个或更多可能的类,那么您的代码已经存在严重问题 - 它们可能共享一个更匹配的超类;无论如何,您不能在 variable 上使用扩展来获取存储在其中的类型来定义函数参数的类型 - 您正在混合运行时和编译时信息跨度>
  • 类型提示必须是静态的,以便 linter 可以验证它们。
  • 不,类型提示仅适用于 IDE/linter,以便更容易发现错误。解释器不使用它们(至少 CPython 不使用)。您不必使用Union;您可以使用@Grismar 在他们的回答中建议的内容。仅当您使用无法修改的内置或第三方类时,才需要联合。

标签: python python-3.x python-typing


【解决方案1】:

这可以使用所有预期类共享的超类来实现您想要的:

from typing import Union
from dataclasses import dataclass


@dataclass
class MyDataMixin:
    pass


@dataclass
class A(MyDataMixin):
    name: str


@dataclass
class B(MyDataMixin):
    age: int


def func(resource: MyDataMixin, value: Union[str, int]):
    return resource

您不能像您尝试做的那样在参数的类型定义中使用扩展,这仅适用于运行时的变量。

正如 @Selcuk 在 cmets 中指出的那样,将其命名为 MyDataMixin 更有意义,因为该类不打算单独使用。您可以更进一步,确保它只是一个抽象类 - 但这超出了问题的范围。

【讨论】:

  • 最好将其命名为Mixin,以便在需要时可以扩展其他(实际)超类。
  • 我应该使用 ABC 而不是 dataclass 作为 Parent 吗?
  • 是的,mixin 本身不一定是数据类,尽管它当然可以。我不会走使用ABC 的路线,除非你有特定的理由想要使用抽象基类,比如要求在每个子类上实现一个抽象方法——但这远远超出了你的要求。仅从共享基类继承就足够了。其他一切都是另一回事。
猜你喜欢
  • 2022-11-22
  • 2017-06-11
  • 1970-01-01
  • 2022-09-27
  • 2022-10-04
  • 2019-07-08
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多