【问题标题】:How to get type hints for an object's attributes?如何获取对象属性的类型提示?
【发布时间】:2020-07-03 23:27:28
【问题描述】:

我想获取对象属性的类型提示。我只能得到类的提示,而不是它的实例。

我曾尝试使用here 中的foo_instance.__class__,但这仅显示类变量。

那么在示例中如何获得bar 的类型提示?

class foo:
    var: int = 42
    def __init__(self):
        self.bar: int = 2

print(get_type_hints(foo)) # returns {'var': <class 'int'>}

【问题讨论】:

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


    【解决方案1】:

    也许这是一个 hack,您必须是实例的创建者,但在某些情况下,使用数据类可以得到您想要的;

    Python 3.7+

    @dataclass
    class Foo:
        bar: str = 2
    
    if __name__ == '__main__':
        f = Foo()
        print(f.bar)
        print(get_type_hints(f))
    
    2
    {'bar': <class 'str'>}
    

    【讨论】:

      【解决方案2】:

      我也遇到了同样的问题。 python doc 不是很清楚,因为这个例子是用现在正式称为数据类的东西制作的。

      Student(NamedTuple):
          name: Annotated[str, 'some marker']
      
      get_type_hints(Student) == {'name': str}
      get_type_hints(Student, include_extras=False) == {'name': str}
      get_type_hints(Student, include_extras=True) == {
          'name': Annotated[str, 'some marker']
      }
      

      它给人的印象是get_type_hints() 直接在课堂上工作。原来get_type_hints() 基于函数而不是类返回提示。这样它就可以与我们知道的 if 一起使用。一个普通的类显然没有在它的声明中被实例化,它没有在 __init__() 方法中设置的任何尚未被调用的变量。如果我们想从类范围的变量中获取类型提示,那也不可能。

      所以您可以在__init__() 上调用它,也就是说,如果变量在参数中传递(是的,我看到它不在您的示例中,但可能对其他人有所帮助,因为我在搜索的几个小时内都没有看到它);

      class foo:
          var: int = 42
          def __init__(self, bar: int = 2):
              self.bar = int
      
      print(get_type_hints(foo.__init__))
      

      最后,对于您的确切示例,我相信您有两个选择。如果您的逻辑允许,您可以实例化一个临时对象并使用del 立即清理它。或者将您的变量声明为具有或不具有默认值的类变量,以便您可以使用get_type_hints() 获取它们并稍后在实例化中分配它们。

      【讨论】:

        【解决方案3】:

        此信息不是evaluated,仅存在于源代码中。 如果您必须获取此信息,您可以使用ast 模块并自己从源代码中提取information,如果您可以访问源代码。

        您还应该问自己是否需要这些信息,因为在大多数情况下,重新评估源代码会很费力。

        【讨论】:

          【解决方案4】:

          提示仅存在于类级别——在创建实例时,其属性的类型将是已分配给它们的任何值的类型。您可以使用内置type() 函数的第一种形式来获取任何实例属性的类型——例如type(foo_instance.var).

          【讨论】:

          • 类型函数返回类型,而不是类型提示。这必须以某种方式实现,因为 pycharm 在访问时会显示属性的类型提示(而不是类型)
          • 它必须使用对象的__class__ 以及属性的名称来显示它。
          • 类型提示存储在类的__annotations__ 属性中,如@Remco Haszing 对链接问题的回答中所述——因为它是一本字典。您可以在其中查找属性的名称。
          • class 只适用于类变量,如果它确实适用于 type() 它只会显示变量内容的类型而不是类型提示,如果为属性分配了不同的类型,pycharm 会正确显示类型提示
          • 注解存储在模块或类级别,因此可以在对象的__class__ 的__annotations__ 属性中找到,但是函数级别的注解不会被评估和存储(参见最后一句Runtime Effects of Type Annotations)。我相信这意味着您想要的信息在源代码之外的任何地方都不可用。
          猜你喜欢
          • 1970-01-01
          • 2010-11-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-22
          • 2019-09-19
          • 2011-01-24
          • 1970-01-01
          • 2021-08-25
          相关资源
          最近更新 更多