Python 编码风格:错误检查和处理
Python coding style: Error checking and handling
我正在 python 编写一些软件,对 python 的首选编码风格有疑问。
想象一下,您有一个函数可以获取一些原始数据,将其解码为字典并打印键值对
def printdata(rawdata):
data = decode(rawdata)
for key, value in data.items():
print(key, value)
这一切都很好,直到 decode
开始到处抛出异常并且整个程序崩溃。因此,我们使用 try/catch 块。但是有几种方法可以做到这一点,我想知道哪种方法是首选。
里面的一切try
def printdata(rawdata):
try:
data = decode(rawdata)
for key, value in data.items():
print(key, value)
except ValueError:
print("error")
只有 decode
在 try
和 return
def printdata(rawdata):
data = None
try:
data = decode(rawdata)
except ValueError:
print("error")
return
for key, value in data.items():
print(key, value)
只有 decode
在 try
和 if
def printdata(rawdata):
data = None
try:
data = decode(rawdata)
except ValueError:
print("error")
if data is not None:
for key, value in data.items():
print(key, value)
所有这些方法都有优点和缺点,我不知道该选择哪一种,也不知道它是否真的重要。
第一个显然是最简单的,但它有一个问题:如果套件其余部分中的任何其他东西可能会引发 ValueError
,它就不是清楚你是否捕获了你期望和想要处理的ValueError
,或者一个可能意味着你的代码中的错误的意外的,所以你可能应该让中止并打印回溯。
当您确定这不是问题时,就去做吧。
虽然确实如此,但您几乎可以肯定会像这样处理错误:
except ValueError as e:
print("error: {!r}".format(e))
…或类似的东西。那样的话,如果你 做 得到那个不可能的意外 ValueError
,你将能够从意外的消息中分辨出来,而不是不知道你已经扔掉了有效的由于最近 3 个月的运行错误导致的数据。
当这不合适时,其他两个想法都 工作 ,但通常更习惯使用 else
块。
def printdata(rawdata):
try:
data = decode(rawdata)
except ValueError:
print("error")
else:
for key, value in data.items():
print(key, value)
如果你确实需要做#2(也许你有,比如说,try
语句中有一堆乱七八糟的 try
语句之类的……),你不需要 data = None
在顶部,不应该有它。 应该 如果不分配给 data
,您就不可能通过 return
。所以,如果以某种方式发生了不可能的事情,你想得到一个异常并看到它,而不是默默地把它当作 None
.
在#3 中,None
实际上是必需的。这是一个问题。 "predeclaring" 变量在设置它们之前的整个想法,然后检查它们是否已被设置,不仅不符合惯用,它还经常掩盖错误——例如,如果 None
是有效的 return 来自 decode
?
"prefered coding style" 是 而不是 "handle" 错误,除非你能 真正地 处理它们。这意味着在库级别,您应该有几乎 none 错误处理 - 只需让错误传播到应用程序级别。在你想要的应用层面
一个顶级错误处理程序,它将正确记录未处理的错误并带有完整的回溯(logging.exception()
是你的朋友),呈现给用户用户友好的错误消息和崩溃。
你实际上可以要求用户更正的地方(再试一次,select 另一个文件,无论如何),做吧。
仅仅打印错误信息——没有完整的回溯等——只是在浪费大家的时间。
我正在 python 编写一些软件,对 python 的首选编码风格有疑问。 想象一下,您有一个函数可以获取一些原始数据,将其解码为字典并打印键值对
def printdata(rawdata):
data = decode(rawdata)
for key, value in data.items():
print(key, value)
这一切都很好,直到 decode
开始到处抛出异常并且整个程序崩溃。因此,我们使用 try/catch 块。但是有几种方法可以做到这一点,我想知道哪种方法是首选。
里面的一切
try
def printdata(rawdata): try: data = decode(rawdata) for key, value in data.items(): print(key, value) except ValueError: print("error")
只有
decode
在try
和return
def printdata(rawdata): data = None try: data = decode(rawdata) except ValueError: print("error") return for key, value in data.items(): print(key, value)
只有
decode
在try
和if
def printdata(rawdata): data = None try: data = decode(rawdata) except ValueError: print("error") if data is not None: for key, value in data.items(): print(key, value)
所有这些方法都有优点和缺点,我不知道该选择哪一种,也不知道它是否真的重要。
第一个显然是最简单的,但它有一个问题:如果套件其余部分中的任何其他东西可能会引发 ValueError
,它就不是清楚你是否捕获了你期望和想要处理的ValueError
,或者一个可能意味着你的代码中的错误的意外的,所以你可能应该让中止并打印回溯。
当您确定这不是问题时,就去做吧。
虽然确实如此,但您几乎可以肯定会像这样处理错误:
except ValueError as e:
print("error: {!r}".format(e))
…或类似的东西。那样的话,如果你 做 得到那个不可能的意外 ValueError
,你将能够从意外的消息中分辨出来,而不是不知道你已经扔掉了有效的由于最近 3 个月的运行错误导致的数据。
当这不合适时,其他两个想法都 工作 ,但通常更习惯使用 else
块。
def printdata(rawdata):
try:
data = decode(rawdata)
except ValueError:
print("error")
else:
for key, value in data.items():
print(key, value)
如果你确实需要做#2(也许你有,比如说,try
语句中有一堆乱七八糟的 try
语句之类的……),你不需要 data = None
在顶部,不应该有它。 应该 如果不分配给 data
,您就不可能通过 return
。所以,如果以某种方式发生了不可能的事情,你想得到一个异常并看到它,而不是默默地把它当作 None
.
在#3 中,None
实际上是必需的。这是一个问题。 "predeclaring" 变量在设置它们之前的整个想法,然后检查它们是否已被设置,不仅不符合惯用,它还经常掩盖错误——例如,如果 None
是有效的 return 来自 decode
?
"prefered coding style" 是 而不是 "handle" 错误,除非你能 真正地 处理它们。这意味着在库级别,您应该有几乎 none 错误处理 - 只需让错误传播到应用程序级别。在你想要的应用层面
一个顶级错误处理程序,它将正确记录未处理的错误并带有完整的回溯(
logging.exception()
是你的朋友),呈现给用户用户友好的错误消息和崩溃。你实际上可以要求用户更正的地方(再试一次,select 另一个文件,无论如何),做吧。
仅仅打印错误信息——没有完整的回溯等——只是在浪费大家的时间。