【问题标题】:Python type hint for (any) class(任何)类的 Python 类型提示
【发布时间】:2017-11-03 15:24:48
【问题描述】:

我想键入提示以下函数:

def get_obj_class(self) -> *class*:
  return self.o.__class__

self.o 可以是任何类型,它是在运行时确定的。

*class* 显然不是这里的答案,因为它是无效的语法。但是正确的答案是什么?我找不到这方面的任何文档,感谢任何帮助。


类似地,如果我有一个函数f(cls: *class*),它返回一个cls 的实例,有没有办法适当地键入提示返回值?

【问题讨论】:

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


    【解决方案1】:

    我建议使用TypeVar 的组合,以指示您的self.o 值可以是任意类型,并以下列方式使用Type

    from typing import TypeVar, Type
    
    T = TypeVar('T')
    
    class MyObj:
        def __init__(self, o: T) -> None:
            self.o = o
    
        def get_obj_class(self) -> Type[T]:
            return type(self.o)
    
    def accept_int_class(x: Type[int]) -> None:
        pass
    
    i = MyObj(3)
    foo = i.get_obj_class()
    accept_int_class(foo)    # Passes
    
    s = MyObj("foo")
    bar = s.get_obj_class()
    accept_int_class(bar)    # Fails
    

    如果您希望o 的类型更加动态,您可以显式或隐式地赋予它Any 的类型。


    关于你的后一个问题,你会这样做:

    def f(cls: Type[T]) -> T:
        return cls()
    

    请注意,在实例化您的类时需要小心——我不记得 Pycharm 在这里做了什么,但我知道 mypy 目前不会检查以确保您正确调用了 __init__ 函数/具有正确数量的参数。

    (这是因为 T 可以是任何东西,但没有办法暗示构造函数应该是什么样子,因此执行此检查最终会变得不可能或非常困难。)

    【讨论】:

    • 我真的不喜欢每次你想构造一个自定义类型时都需要创建一个 named TypeVar 对象。我认为在我的情况下,我宁愿坚持type。不过谢谢你介绍这个
    • @nO_OnE_910 -- 在定义泛型类和函​​数时,您可以重用相同的 TypeVar 变量。您可能会发现这不那么令人反感,因为您只引入了一个命名的 TypeVar 对象(然后您可以重用),而不是每个泛型类或函数一个。
    【解决方案2】:

    我认为这会起作用:

    def get_obj_class(self) -> type
        return self.o.__class__
    

    【讨论】:

    • + 为简单起见,尽管typing.TypeVar 似乎是正确的解决方案
    【解决方案3】:

    typing.Type 怎么样?

    https://docs.python.org/3/library/typing.html#typing.Type

    这似乎很合适——因为 __class_ 应该总是返回一个类型

    是的,这行得通(即使 Pycharm 也不会抱怨:

    import typing
    
    
    def test(t: object) -> typing.Type:
        return t.__class__
    
    class Dummy(object):
        pass
    
    test(Dummy())
    

    关于你的第二个问题:那应该是通用的:https://docs.python.org/3/library/typing.html#user-defined-generic-types

    【讨论】:

    • 为什么是typing.Type 而不仅仅是type
    • @nO_OnE_910 我更喜欢使用打字模块来保持连贯的风格。我的大部分回报都是打字.X,所以对我来说似乎更自然
    猜你喜欢
    • 2023-03-29
    • 2020-01-14
    • 2020-06-12
    • 2019-05-15
    • 2021-10-19
    • 2011-12-11
    • 2022-09-29
    • 1970-01-01
    相关资源
    最近更新 更多