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__
的类型都可以作为候选。在内置函数中,这包括 int
、float
、complex
、long
、list
、tuple
、string
、unicode
、bytearray
、buffer
等
如果我们在前面的示例中添加更多上下文,类型推断的工作原理就会变得更加清晰:
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"???
在这种情况下,我们最多只能说它是 string
或 int
。由于添加了这个条件(基于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 是一种静态类型的语言。
动态类型的缺点之一是无法在运行前知道类型。但在我看来,如果给出完整的源代码,应该有一些(可能尚未开发)方法来测试代码中的每种情况,这样运行时崩溃的可能性就会降低。这什么时候不可能?
考虑一下:
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__
的类型都可以作为候选。在内置函数中,这包括 int
、float
、complex
、long
、list
、tuple
、string
、unicode
、bytearray
、buffer
等
如果我们在前面的示例中添加更多上下文,类型推断的工作原理就会变得更加清晰:
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"???
在这种情况下,我们最多只能说它是 string
或 int
。由于添加了这个条件(基于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 是一种静态类型的语言。