Python Try/Catch:异常时直接执行下一条语句

7 投票
4 回答
21087 浏览
提问于 2025-04-18 00:28

假设我有以下的Python代码:

x = some_product()
name        = x.name
first_child = x.child_list[0]
link        = x.link
id          = x.id

在第三行可能会出现一个问题,当 x.child_listNone 的时候。这显然会导致一个 TypeError,错误信息是:

'NoneType' Object has no attribute '_____getitem_____'

我想要做的是,每当 x.child_list[0] 报出 TypeError 的时候,就简单地忽略这一行,继续执行下一行,也就是 "link = x.link"...

所以我在想,可能可以这样做:

try:
    x = some_product()
    name        = x.name
    first_child = x.child_list[0]
    link        = x.link
    id          = x.id
Except TypeError:
    # Pass, Ignore the statement that gives exception..

那我应该在 Except 块下面放什么呢?或者有没有其他方法可以做到这一点?

我知道我可以用 If x.child_list is not None: ...,但我的实际代码要复杂得多,我在想有没有更符合Python风格的方法来处理这个问题。

4 个回答

2

当你捕捉到一个异常时,你会直接跳出尝试的范围。更好的办法是通过修改你那行代码来防止异常发生,变成:

if x.child_list[0] != None:
    first_child = x.child_list[0]

希望这对你有帮助。

编辑

因为你修改了问题,并且不想要这个解决方案,那么唯一的办法就是在那行代码之后立即捕捉异常:

try:
    first_child = x.child_list[0]
except TypeError:
    pass
2

在第3行可能会出现一个问题,当 x.child_list 是 None 的时候。这显然会导致一个类型错误,错误信息是:

我觉得用异常来处理这个问题不是个好办法。字符串、列表、元组这些类型都有getitem方法,或者其他自定义的类也可以包含这个方法。如果你只想处理元组或列表,这段代码会对你有帮助:

x = some_product()
name = x.name
first_child = (lambda x: x[0] if isinstance(x, list) or isinstance(x, tuple) else None)(x.child_list)
link = x.link
id = x.id

另外,请阅读一下 PEP8,了解一下 Python 代码的格式规范。

3

因为你只想在那一行处理这个错误,所以只在那一行捕捉这个错误。

x = some_product()
name        = x.name
try:
  first_child = x.child_list[0]
except TypeError:
  first_child = None
link        = x.link
id          = x.id
11

你想的其实是这个:

try:
    x = some_product()
    name        = x.name
    first_child = x.child_list[0]
    link        = x.link
    id          = x.id
except TypeError:
    pass

不过,最好的做法是尽量少在 try/catch 这个块里放东西:

x = some_product()
name = x.name
try:
    first_child = x.child_list[0]
except TypeError:
    pass
link = x.link
id = x.id

不过,你真正应该做的是完全避免使用 try/catch,可以试试这样做:

x = some_product()
name = x.name
first_child = x.child_list[0] if x.child_list else "no child list!"
# Or, something like this:
# first_child = x.child_list[0] if x.child_list else None
link = x.link
id = x.id

当然,最终的选择还是要看你想要的效果——比如你想不想让 first_child 变成未定义等等。

撰写回答