如何使用 __future__ 注释从 self.__annotations__ 获取可调用的 class 对象?

How to get callable class objects from self.__annotations__ with __future__ annotations?

如果使用 py3.10 from __future__ import annotations,从注释中查找 class 的最佳方法是什么?以前,self.__annotations__[name] 会给你一个对象,但现在 returns 是一个字符串。您可以使用 globals() 如图所示,但这对我来说似乎不正确。有没有更好的方法?

@dataclass
class Person:
    height: float
    def stack(self, other: Person):
        return Person(self.height + other.height) #gymnasts
@dataclass
class Chair:
    height: float
    def stack(self, other: Chair):
        return Chair(0.6*(self.height + other.height) ) #stackable chairs
@dataclass
class Room:
    person: Person
    chair: Chair
    
    def set(self, name: str, val: float):
        # lots of complicated validation
        # factory = self.__annotations__[name] # this worked before from __future__ import annotations
        factory = globals()[self.__annotations__[name]]
        self.__setattr__(name, factory(height=val))

使用typing.get_type_hints访问“函数、方法、模块或class对象”的求值__annotations__。值得注意的是,它了解基本继承——它合并继承的注释并使用当前 class 的 globals 而不是方法的模块。

@dataclass
class Room:
    person: Person
    chair: Chair

    def set(self, name: str, val: float):
        factory = get_type_hints(type(self))[name]
        self.__setattr__(name, factory(height=val))

虽然 typing.get_type_hints 比仅检查 globals 做了一些额外的工作,但 __future__.annotations 本质上会删除非全局信息。对于在 locals 范围内定义的 classes 的罕见情况,必须明确提供命名空间。