Python:try/except 块后异常消失

Python: Exception is gone after try/except block

提问人:Grzegorz Z. 提问时间:9/27/2023 更新时间:9/27/2023 访问量:44

问:

如果我复制了一些线程,我真的很抱歉,但我真的找不到答案。 所以,我有一小段代码:

exception = None
updated_at = None
test_str = "obviously wrong"

for datetime_format in ['%d-%b-%Y %H:%M', '%Y-%m-%d %H:%M']:
    try:
        updated_at = int(datetime.strptime(test_str, datetime_format).timestamp())
        break
    except Exception as exception:
        pass

if updated_at is None:
    raise exception

基本上,如果第一个日期格式错误,我不想打破循环,但是如果我无法解析日期,我想稍后抛出异常。 最初我以为代码没问题,但是在测试运行后,当我收到错误时,我有点震惊:

在赋值之前引用了异常局部变量“exception”!

所以似乎这个异常变量以某种方式被清除并消失了? 我真的不明白这是怎么回事? 如果有人能向我解释这里发生的事情,我将不胜感激:)

Python 异常 错误处理

评论

0赞 JRiggles 9/27/2023
你第一次成功时就进入了循环,所以如果它成功了,就没有价值了breakstrptimeexception
0赞 Grzegorz Z. 9/27/2023
@JRiggles但是如果它成功了,则不应引发 if 检查,因为 updated_at 不会是 None ?
0赞 JRiggles 9/27/2023
啊,真的。然而,在语句中看到一个有点奇怪breaktry
0赞 norman 9/27/2023
有趣的是,在第一行中声明的“异常”不仅没有得到引发的异常,甚至在 except 块之后也未定义:如果引发异常,在 for 循环之后访问异常时,我会得到一个“无法访问局部变量'异常',其中它与值无关”。我没想到会这样。
0赞 Codist 9/27/2023
break 会从 for 循环中突围 - 而不是 try/except 块。你是说你只想在两次解析日期的尝试都失败时引发异常吗?

答:

3赞 sudden_appearance 9/27/2023 #1

这是因为由于某些特定原因,它不会存储在块之外:except ... as eeexcept

try:
    1 / 0
except ZeroDivisionError as e:
    ...

print(e)  # NameError: name 'e' is not defined

应显式分配:exception

exception = None
updated_at = None
test_str = "obviously wrong"

for datetime_format in ['%d-%b-%Y %H:%M', '%Y-%m-%d %H:%M']:
    try:
        updated_at = int(datetime.strptime(test_str, datetime_format).timestamp())
        break
    except Exception as e:
        exception = e

if updated_at is None:
    raise exception

评论

0赞 Grzegorz Z. 9/27/2023
谢谢。今天刚学到了新东西!
2赞 Codist 9/27/2023 #2

IIUC:仅当两次解析字符串的尝试都失败时,才希望引发异常。如果是这种情况,那么:

from datetime import datetime

test_str = "obviously wrong"

for datetime_format in ['%d-%b-%Y %H:%M', '%Y-%m-%d %H:%M']:
    try:
        updated_at = int(datetime.strptime(test_str, datetime_format).timestamp())
        break
    except Exception as exception:
        e = exception
else:
    raise e