Python 什么时候无法在运行前确定对象的类型?

When is it impossible for Python to determine the type of the object before runtime?

动态类型的缺点之一是无法在运行前知道类型。但在我看来,如果给出完整的源代码,应该有一些(可能尚未开发)方法来测试代码中的每种情况,这样运行时崩溃的可能性就会降低。这什么时候不可能?

考虑一下:

def aFunction(textInput):
    if textInput == "I want a number this time":
        return 10
    else:
        return "a string"


value = aFunction(input("Type something\n"))
print(type(value))

函数的 return 值的类型取决于输入。

此外,考虑一下:

def anotherFunction(textInput):
    if isInputValid(textInput):
        return transformTheInputSomehow(textInput);
    else:
        return None

None实际上在Python中有一个class (NoneType)

另一种类型推断不明确的情况是,如果整个程序包含[=36​​=]

def foo(x):
    return x * 3

在这种情况下,任何实现 __mul__ 的类型都可以作为候选。在内置函数中,这包括 intfloatcomplexlonglisttuplestringunicodebytearraybuffer

如果我们在前面的示例中添加更多上下文,类型推断的工作原理就会变得更加清晰:

def foo(x):
    return x * 3

y = "hello"
foo(y) #=> "hellohellohello"

在这种情况下,我们可以简单地通过使用 copy propagation 来执行此检查,我们看到我们正在传递 y,我们知道它包含 "hello",到 foo,因此,在这种情况下,foo(x) 将被推断为 foo(x: string) -> string

不幸的是,正如@Pablo 指出的那样,一旦我们添加条件,推断类型就会再次变得不明确:

def foo(x):
    return x * 3

y = "hello"

if some_other_function():
    y = 3

foo(y) #=> 9 or "hellohellohello"???

在这种情况下,我们最多只能说它是 stringint。由于添加了这个条件(基于some_other_function()的结果),我们不知道是否会达到foo(y),如果达到了,我们不知道是什么类型y 会。

在 JavaScript(另一种 duck-typed 类型系统比 Python 弱的语言)中,Facebook 的 Flow can perform reasonable static type checking. Flow supports type annotations to further aid its analysis, but works well without them. Similarly, function annotations in Python 3 could certainly aid this sort of static analysis. Even without annotations, though, type checking tools like this seem to already exist (See: ). An example of this is PySonar2.

等工具

最后,Python 当然 可以 执行此推理。 Python 被解释的事实在这种情况下没有任何意义。 OCaml 有一个编译器附带的解释器,但 OCaml 是一种静态类型的语言。