python - Python 异常指南解释
问题描述
在 Google 的 python 样式指南文档中,他们提到了以下内容:
请注意,在文档字符串的“引发:”部分中没有提到 ValueError 的引发,因为不适合保证对 API 滥用的这种特定行为反应。
为什么不合适?这是否意味着首先不应该像这样使用 ValueError ?
def connect_to_next_port(self, minimum: int) -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError(f'Min. port must be at least 1024, not {minimum}.')
port = self._find_next_open_port(minimum)
if not port:
raise ConnectionError(
f'Could not connect to service on port {minimum} or higher.')
assert port >= minimum, (
f'Unexpected port {port} when minimum was {minimum}.')
return port
解决方案
ConnectionError
可以是根据其记录的用法使用该函数的结果。
然而ValueError
, 只是公然违反函数的先决条件的结果。你已经被警告过,这minimum >= 1024
一定是真的。您不需要记录违反该警告的后果。
例如,您不需要try
语句来处理ValueError
; 您可以在调用函数之前检查参数的值以避免它。(在这种情况下,请求宽恕并不比允许更容易。)
您确实需要一个try
语句来处理ConnectionError
,因为无法预测它可能会发生。为了知道ConnectionError
可能会提出 a,这需要记录在案。
从具有静态类型检查的总体语言的角度来看,区别在于您可以通过使用适当的参数类型来避免错误,而您可以通过使用适当的返回类型来避免错误。考虑类似 Haskell 的伪代码中的偏函数。
type ValidPort = Int
connect_to_next_port :: ValidPort -> ValidPort
connect_to_next_port = ...
但不仅仅是 anyInt
是有效的端口。只有 1024 到 65535 之间的整数(TCP/IP 中的端口是 16 位值)。所以想象我们有一种方法来定义一个受限类型,我们可以消除ValueError
with
type ValidPort = { x :: Int | 1024 <= x <= 65535 }
connect_to_next_port :: ValidPort -> ValidPort
connect_to_next_port = ...
但我们可能找不到返回的港口。我们没有引发异常,而是返回 type 的东西Maybe ValidPort
,您可以将其视为包含 type 值ValidPort
和 value的包装器None
(大致对应Nothing
于 Haskell 中的值)。
type ValidPort = { x :: Int | 1024 <= x <= 65535 }
connect_to_next_port :: ValidPort -> Maybe ValidPort
connect_to_next_port = ...
也就是说,我们记录了可以编码为返回类型的异常,而不是可以通过适当的参数类型消除的异常。
推荐阅读
- spring-boot - java.lang.NoSuchMethodError: javax.ws.rs.core.UriBuilder.resolveTemplates(Ljava/util/Map;)Ljavax/ws/rs/core/UriBuilder
- r - 在 R 中更改数据框的字符
- azure-web-app-service - 如何从 Internet 访问 Azure Web App Container
- python - Python 类型弃用
- java - Java:java.lang.NoSuchMethodError:'void org.apache.fontbox.cmap.CMapParser。
(布尔值) - opengl - CMake 找不到 OpenGL 库
- python - 简单 ctype 数组的类型注释
- audio - 从缩放会议中的每个参与者获取单独的音频
- reactjs - 大家好,有一些问题 RTCPeerConnection.onicecandidate 不起作用
- openapi - 为什么 openapi-generator 会创建 InlineObjects?