【问题标题】:TypeError: typing.Any cannot be used with isinstance()TypeError: typing.Any 不能与 isinstance() 一起使用
【发布时间】:2021-09-02 23:12:14
【问题描述】:

我想知道为什么 Python 的打字模块不支持isinstance(<obj>, Any) 并引发TypeError。我希望它总是返回True。为什么它并不总是返回True,是否有特定原因?

  • 引发了 TypeError here
  • TypeError 示例:
>>> from typing import Any
>>> isinstance(1, Any)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/peter/miniconda3/envs/prefect_utils/lib/python3.9/typing.py", line 338, in __instancecheck__
    raise TypeError(f"{self} cannot be used with isinstance()")
TypeError: typing.Any cannot be used with isinstance()

【问题讨论】:

  • 因为如果答案总是True,你为什么要首先做这个检查?
  • 如果你想要一个任何对象都将被视为isinstance的实例的类型,请考虑object
  • @deceze:这种逻辑会让我相信 dunder 检查会无条件返回 true,不会引发异常。我认为这样做可能会产生不良影响。
  • 打字中的大多数东西都不是用于运行时类型检查的。任何也不例外。大多数类型不能准确地动态检查,所以打字避免假装它是可能的。
  • @deceze :因为我在运行时检查各种类型(不仅包括Any),以检查给定对象是否确实是给定类型。在这种情况下,isinstance(obj, Any) 返回True 而不是引发异常是有意义的。这也是imo让它始终返回True的正当理由。

标签: python typing


【解决方案1】:

Any 类文档字符串似乎说明了原因:

"""Special type indicating an unconstrained type.

- Any is compatible with every type.
- Any assumed to have all methods.
- All values assumed to be instances of Any.

Note that all the above statements are true from the point of view of
static type checkers. At runtime, Any should not be used with instance
or class checks.
"""

def __instancecheck__(self, obj):
    raise TypeError("Any cannot be used with isinstance().")

def __subclasscheck__(self, cls):
    raise TypeError("Any cannot be used with issubclass().")

如果将这些对象视为实际实例或子类,如果它们没有提供实例或子类应该提供的确切内容,则可能会导致问题。相反,它们“伪造”了这样一个事实,即它们可以是任何东西,但不会因为在类型层次结构中被这样对待而造成损害。

【讨论】:

    【解决方案2】:

    打字中的大多数事情都不适用于运行时类型检查。大多数类型无法进行明智的动态检查,因此打字避免假装它是可能的。


    Any 类型不是正确的类型——它在任何用法中都与任何类型兼容。根据用途,它可以是另一种类型的超类型和子类型。
    最突出的是,Any 支持所有操作。因此,isinstance(x, Any) == True 意味着x 支持所有 操作,无论x'具体类型如何。这对于大多数正确的类型来说是不明智的。


    例如,考虑将整数检查为“Any 的实例”,这意味着它支持切片:

    x = 3
    if isinstance(x, Any):  # x supports any operation in this block
        print(x[:3])        # slicing is part of "all operations"
    

    【讨论】:

    • 这对我来说很有意义,谢谢。供参考:this SO answer on a related question通过比较Anyobject更详细地解释了这个问题:stackoverflow.com/a/39817126/919431
    猜你喜欢
    • 2018-11-02
    • 1970-01-01
    • 2014-12-28
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 2017-04-14
    • 2016-09-16
    相关资源
    最近更新 更多