【问题标题】:Type alias with union使用 union 键入别名
【发布时间】:2022-09-28 13:08:41
【问题描述】:

我目前有这种类型的别名,以及我的代码中的一些相关函数:

Constant = int

def operation(data: Union[Constant, OtherTypes]):
    if isinstance(data, Constant):
        # do something
    else:
        # do something else

现在,我想让Constant 也代表另一种类型,比如浮点数。这个常量别名在我的代码库中使用,所以我不想到处更改它。

我努力了:

Constant = (int, float)

这适用于isinstance,但Unions 抱怨\"TypeError: Union[arg, ...]: each arg must be a type.\"

然后我尝试过:

Constant = Union[int, float]

现在,问题出现在isinstance;我得到\"TypeError: Subscripted generics cannot be used with class and instance checks\"

有没有办法做我想要实现的目标?

谢谢。

    标签: python


    【解决方案1】:

    isinstance 支持 Unions 附带 python 3.10 。因此,从该版本开始,第二个解决方案将起作用。

    https://peps.python.org/pep-0604/

    【讨论】:

    • 我仍然想知道是否可以使用以前版本的 Python 解决这个问题。
    • 这是特例,一般情况下isinstance不适用于类型注释, 只有实际类型
    【解决方案2】:

    正如 Pankkake 在他们的回答中提到的,对于 Python 3.10,您只需执行 Constant = int | float 即可,它可以在任何地方工作。

    但是,如果您必须支持旧版本的 Python,您可以使用 Frank、MSeifert 和 Richard Xia 在Check a variable against Union type at runtime in Python 3.6 中提供的解决方案:

    Python 3.8+

    使用typing.get_args(tp) 函数获取具有联合类型的元组,您可以在isinstance 中使用它:

    from typing import Union, get_args
    
    Constant = Union[int, float]
    
    def operation(data: Union[Constant, OtherTypes]):
        if isinstance(data, get_args(Constant)):
            # do something
        else:
            # do something else
    

    get_args 仅返回类型的参数,而不验证该类型是 Union 还是其他泛型类型,这似乎足以满足您的要求。

    如果由于某种原因您还需要在运行时检查 Constant 类型是否是 Union ,请使用 typing.get_origin(tp) 函数:

    from typing import Union, get_origin
    
    if get_origin(Constant) is Union:
        # do something
    

    Python 3.5.3+

    在 3.8 之前,get_argsget_origin 函数不存在,因此您需要改用未记录的属性 __args____origin__

    def operation(data: Union[Constant, OtherTypes]):
        if isinstance(data, Constant.__args__):
            # do something
        else:
            # do something else
    

    这仍然适用于 3.10.5,但由于这些属性未记录在案,因此在任何未来的 Python 版本中,上面的 sn-p 可能会立即停止工作。

    Python 3.5.0 到 3.5.2

    类型提示在 Python 的 3.5.0 版本中实现。在 3.5.2 之前,获取联合参数的属性名称是 __union_params__

    def operation(data: Union[Constant, OtherTypes]):
        if isinstance(data, Constant.__union_params__):
            # do something
        else:
            # do something else
    

    当然,这个属性只存在于Union类型,所以如果你需要检查一个类型是否为Union,检查该属性是否存在。

    请注意,这仅适用于 Python 3.5.2,因为在 3.5.3 中他们将属性名称更改为 __args__

    【讨论】:

      猜你喜欢
      • 2020-04-23
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      • 2021-10-25
      相关资源
      最近更新 更多