如何将try/except写成一行?

144 投票
17 回答
166460 浏览
提问于 2025-04-15 20:53

在Python中,有没有办法把try/except写成一行呢?

类似于这样...

b = 'some variable'
a = c | b #try statement goes here

这里的b是一个已经声明的变量,而c是一个没有声明的变量...所以c会报错,而a会变成b...

17 个回答

96

这段内容虽然有点小技巧,但我在调试的时候常常用到它,特别是在我想写一系列操作的时候:

exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()"
print "The problem is %s" % problem[1]

大多数情况下,我并不在意不能用单行的try-except语句,但有时候我在实验时,希望在交互式解释器中一次性调出一整段代码,这样我就可以进行调整,这个小技巧就派上用场了。

如果你想实现某个具体的功能,可以试试 locals().get('c', b);不过,理想情况下,使用一个真正的字典会比使用局部上下文更好,或者在运行可能会设置c的代码之前,先把c赋值为None。

126

在Python3中,你可以使用 contextlib.suppress 这个工具:

from contextlib import suppress

d = {}
with suppress(KeyError): d['foo']
78

在Python中,不能把try/except块压缩成一行。

而且,不知道一个变量是否存在是件不好的事情,尤其是在Python中,这和其他一些动态语言不太一样。更安全的做法(也是大家普遍采用的风格)是先给所有变量赋值。如果有可能没有被赋值,就先把它们设为None(或者0''等更合适的值)。


如果你给所有感兴趣的变量赋值,那你就有一些选择。

  • 最好的选择是使用if语句。

    c = None
    b = [1, 2]
    
    if c is None:
        a = b
    else:
        a = c
    
  • 如果想要一行代码,可以用条件表达式。

    c = None
    b = [1, 2]
    a = c if c is not None else b
    
  • 有些人会滥用or的短路特性来实现这个功能。这很容易出错,所以我从来不这样做。

    c = None
    b = [1, 2]
    a = c or b
    

    考虑以下情况:

    c = []
    b = [1, 2]
    a = c or b
    

    在这个例子中,a可能应该[],但它实际上是[1, 2],因为在布尔上下文中[]被认为是假的。由于有很多值会被认为是假的,我不使用or这个技巧。(这和人们在说if foo:时其实想表达if foo is not None:是同样的问题。)

撰写回答