【问题标题】:TypeHinting function that give Types and returns Objects of these Types给出类型并返回这些类型的对象的类型提示函数
【发布时间】:2021-12-15 18:31:32
【问题描述】:

我想用python制作实体组件系统(ECS)。

我让Entity 上课:

from typing import Optional, TypeVar, Type


T = TypeVar('T')


class Entity:
    def __init__(self):
        self.components = []

    def add_component(self, c):
        self.components.append(c)

    def get_first_component(self, Type: Type[T]) -> Optional[T]:
        for c in self.components:
            if isinstance(c, Type):
                return c

    def get_first_components(self, *Types):
        res = []
        for Type in Types:
            res.append(self.get_first_component(Type))
        return res

get_first_component 的类型提示很简单,但我不明白如何为get_first_components 函数进行类型提示。该函数给出类型列表并返回这些类型的对象列表。

例子:

e.get_first_components(Position, Health) # returns [Position(2, 2), Health(10, 10)]

我是这样看的:

A = TypeVar('A')
B = TypeVar('B')

def f(Types: [Type[A], Type[B], ...]) -> [A, B, ...]:
    # some code ...

对不起,我的英语不好:(

需要在系统中进行类型提示:

class MoveSystem(System):
    def __init__(self) -> None:
        pass

    def run_for_entity(self, e: Entity):
        pos, m2 = e.get_first_components(Pos2, Move2)
        if m2.active: # <- no type hinting after typing "m2."
            pos.x += m2.dx
            pos.y += m2.dy
            m2.active = False

【问题讨论】:

  • *Types: Type[T]?而返回类型只是-&gt; List[Optional[Type[T]]]
  • @juanpa.arrivillaga:我认为返回值是List[Optional[T]],因为列表中的值是参数中给出的类型的实例。我也不确定这是否可行,因为正在寻找的类型可能没有共同的基类(object 除外),所以T 的描述性不会很强。

标签: python python-3.x game-engine type-hinting


【解决方案1】:

Python 的类型提示系统无法以您想要的方式描述您的函数。您需要能够描述一系列不同类型的任意长度,然后并行地描述这些类型的对象。不幸的是,这目前是不可能的。

关于你能做的最好的事情是:

def get_first_components(self, *Types: Type[T]) -> List[Optional[T]]:

但这可能不会达到你想要的效果。 T 将匹配您传递给函数的类型的公共基类,如果您的类没有任何其他公共基类,则可能是 object。这意味着,当您将返回的列表解压缩为单独的变量时,类型检查器会将它们全部识别为基类的实例,而不是每个都具有您在相应位置传递的特定类型。

您可以通过使用具有可用类型提示的其他方法来使您的调用代码正常工作:

pos = e.get_first_component(Pos2)  # will be identified as Optional[Pos2]
m2 = e.get_first_component(Move2)  # will be identified as Optional[Move2]

附带说明,由于您获得的值是Optional,因此您可能需要检查它们是否为None。如果你让类型提示正常工作,如果你在没有首先检查的情况下执行m2.active 之类的操作,则会收到警告,因为None 没有active 属性。

【讨论】:

    猜你喜欢
    • 2020-12-10
    • 2015-11-23
    • 2017-04-03
    • 2022-01-16
    • 2017-11-21
    • 2020-12-19
    • 2013-01-31
    • 2023-04-04
    • 2021-02-17
    相关资源
    最近更新 更多