我有一个check_value
函数,该函数期望参数value
和value_type
,将type(value)
与value_type
进行比较,并根据结果返回值或提高Exception
。现在,我想使用类型提示来注释参数和返回类型。
def check_value(value: "value_type", value_type: type) -> "value_type":
if type(value) is value_type:
return value
else:
raise Exception(f"Value '{value}' should be of type '{value_type}' instead of type '{type(value)}'.")
if __name__ == '__main__':
print(check_value(2, int)) # works, returns
print(check_value(2, str)) # works, raises Exception
参数value_type
的注释工作正常,但是将forward referencing value_type
作为类型提示(因为value
/ the returned value
的类型是value_type
)在Pycharm_2018.1.4中引发警告(请参见下图)。
是Pycharm中的错误吗?我做错什么了吗?这样不能使用类型提示吗?
谢谢!
答案 0 :(得分:2)
我认为Python的静态类型检查系统不能支持您所展示的功能。这是因为value_type
的值根本不是静态的,而是在运行时确定的。我认为,您可以做的最好的事情是这样的:
T = typing.TypeName("T")
def check_value(value: T, value_type: type) -> T:
...
value_type
参数应绑定到T
表示的相同类型这一事实不能用类型注释来表示。
但是,如果您要进行静态类型检查,则不需要这种功能。如果您已经正确注释了value
的来源以及将要使用的地方,则静态类型检查器应该已经知道它是否为适当的类型,而无需使用函数来检查它运行。由于print
接受Any
个参数,因此它在您的示例中实际上并不起作用,但是对于专门期望int
或str
的函数,您只需传递值并让类型检查器发现问题:
def source_of_ints() -> int:
return 2
def function_that_takes_an_int(value: int) -> None:
print(value) # or whatever
def function_that_takes_a_str(value: str) -> None:
print(value) # or whatever
if __name__ == '__main__':
value = source_of_ints() # value's type can be inferred by static type checker
function_that_takes_an_int(value) # works and passes type check too
function_that_takes_a_str(value) # works at runtime, but type checker will see an error