gender = readFromDB(...) # either 'm' or 'f'
if gender == 'm':
greeting = 'Mr.'
elif gender == 'f':
greeting = 'Ms.'
else:
# What should this line say?
def check(condition, msg=None):
if not condition:
raise ValueError(msg or '')
check(gender in ('m', 'f'))
if gender == 'm':
greeting = 'Mr.'
else:
greeting = 'Ms.'
>>> from typing_extensions import assert_never
>>> assert_never(123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/homestar/tmp/.direnv/python-3.9.15/lib/python3.9/site-packages/typing_extensions.py", line 1993, in assert_never
raise AssertionError("Expected code to be unreachable")
AssertionError: Expected code to be unreachable
下面是一个函数的例子,它的返回类型注解是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
8条答案
按热度按时间r1wp621o1#
4dbbbstv2#
你可以抛出一个异常:
或者如果希望数据库只返回'm'或'f',则使用assert False:
o7jaxewo3#
这取决于你对性别是
'm'
还是'f'
的确定程度。如果你非常确定,使用
if...else
而不是if...elif...else
,这样对每个人来说都更容易。但是,如果有任何错误的数据,你可能应该提出一个异常,使测试和错误修复更容易。在这种情况下,你可以使用性别中立的问候语,但对于任何更大的,特殊的值只会使错误更难找到。
xggvc2p64#
我真的觉得有个地方可以放这个。
所以你能做到
我认为这是最有意义的错误信息。这种事情只能通过设计错误(或糟糕的维护,这是一回事)产生
eiee3dmh5#
我有时会这样做:
我认为这很好地告诉了代码的读者,(在这种情况下)只有两种可能性,以及它们是什么。尽管你可以提出一个比AssertionError更具描述性的错误。
kiayqfof6#
这完全取决于您希望错误发出的信号,但在这种情况下,我会使用字典:
如果gender既不是m也不是f,这将引发一个包含意外值的KeyError:
如果你想在消息中获得更多细节,你可以捕获并重新提出它:
91zkwejq7#
到目前为止,我通常使用John Fouhy的答案的变体-但这并不完全正确,正如Ethan指出的那样:
使用assert的主要问题是,如果任何人使用-O或-OO标志运行您的代码,则assert会被优化。正如Ethan在下面指出的那样,这意味着您现在根本没有数据检查。Assert是一种开发辅助工具,不应该用于生产逻辑。我将养成使用check()函数的习惯-这允许像assert一样使用干净的调用语法:
回到最初的问题,我认为在if/else逻辑之前使用assert()或check()更容易阅读,更安全,更明确:
gblwokeq8#
在python 3.11+版本中,你可以使用和
typing.assert_never
来Assert不可达性,这种方式可以通过静态类型检查器(如mypy
和pyright
)进行验证。(在python 3.11之前的版本中,你需要从typing_extensions
模块导入assert_never
。)下面是一个使用
typing.assert_never
和typing.Literal
来AssertOP问题中的else
块不可访问的示例:静态类型检查器将验证上面的
else
-块确实是不可访问的。如果在运行时到达assert_never
块,它将抛出AssertionError
:下面是一个函数的例子,它的返回类型注解是
typing.NoReturn
:typing.Never
类型在python〉=3.11的typing
模块中可用,在python的早期版本的typing_extensions
中可用。下面是另一个例子,使用
if
/elif
/else
块来匹配变量的类型:有关更多示例,包括与枚举类型的值进行匹配,请参阅Unreachable Code and Exhaustiveness Checking上的Python类型文档。