如何标记不可达的Python代码
在Python中,怎么用一种“Python风格”的方式来标记那些永远不会被执行的代码呢?就像下面这个例子:
gender = readFromDB(...) # either 'm' or 'f'
if gender == 'm':
greeting = 'Mr.'
elif gender == 'f':
greeting = 'Ms.'
else:
# What should this line say?
8 个回答
在Python 3.11及以上版本中,你可以使用typing.assert_never
来确认某段代码是不可达的,这种方式可以被静态类型检查工具,比如mypy
和pyright
验证。
from typing import assert_never
foo: int = 123
if isinstance(foo, str):
assert_never(foo) # unreachable
静态类型检查工具会检查上面的if
块确实是不可达的。如果在运行时意外到达了assert_never
的那部分代码,它会抛出一个AssertionError
错误:
>>> from typing import assert_never
>>> assert_never(123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/.../lib/python3.11/typing.py", line 2464, in assert_never
raise AssertionError(f"Expected code to be unreachable, but got: {value}")
AssertionError: Expected code to be unreachable, but got: 123
在Python 3.11之前的版本中,你需要从typing_extensions
模块中导入assert_never
。
from typing_extensions import assert_never # python < 3.11
示例
assert_never
与typing.Literal
下面是一个使用typing.assert_never
和typing.Literal
的例子,来确认OP问题中的else
块是不可达的:
from typing import Literal
from typing_extensions import assert_never
var: Literal["m", "f"] = "m"
if var == "m":
...
elif var == "f":
...
else:
assert_never(var) # unreachable
assert_never
与typing.NoReturn
这里是一个函数的例子,它的返回类型注解是typing.NoReturn
:
import time
from typing import NoReturn
from typing_extensions import Never, assert_never
def foo() -> NoReturn:
while True:
time.sleep(1)
bar: Never = foo()
assert_never(bar) # unreachable
typing.Never
类型在Python 3.11及以上版本的typing
模块中可用,而在早期版本中则在typing_extensions
中可用。
assert_never
与typing.Union
这是另一个例子,使用if
/elif
/else
块来匹配一个变量的类型:
from typing import Union
from typing_extensions import assert_never
var: Union[int, str, float] = "123"
if isinstance(var, int):
...
elif isinstance(var, str):
...
elif isinstance(var, float):
...
else:
assert_never(var) # unreachable
想要查看更多示例,包括如何匹配枚举类型的值,可以查看Python类型文档中的不可达代码和穷尽性检查。
你可以抛出一个异常:
raise ValueError("Unexpected gender; expected 'm' or 'f', got %s" % gender)
或者如果你希望数据库只返回'm'或'f',可以使用assert False:
assert False, "Unexpected gender; expected 'm' or 'f', got %s" % gender
在编程中,有时候我们需要处理一些数据,这些数据可能来自不同的地方,比如用户输入、文件或者网络请求。为了让程序能够理解这些数据,我们通常需要将它们转换成一种程序能处理的格式。
比如说,如果我们从一个网页上获取了一些信息,这些信息可能是以文本的形式存在的。我们需要把这些文本解析成程序能理解的结构,比如数组或者对象。这样,程序才能对这些数据进行操作,比如显示、计算或者存储。
在这个过程中,我们可能会用到一些工具或者库,它们可以帮助我们更方便地处理这些数据。使用这些工具,就像是用一个强大的助手来帮我们完成繁琐的工作,让我们能更专注于编写程序的逻辑。
总之,数据处理是编程中非常重要的一部分,掌握了这部分内容,我们就能更好地与程序进行互动,创造出更有趣的功能。
raise ValueError('invalid gender %r' % gender)