python中有没有办法将try / except变成一行?
就像是...
b = 'some variable'
a = c | b #try statement goes here
哪里b
是声明的变量,c
而不是...所以c
会引发错误并a
变成b
...
Answers:
在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]
因为[]
在布尔上下文中为false。因为有很多可能为假的值,所以我不使用or
技巧。(这是人们在表达if foo:
自己的意思时遇到的相同问题if foo is not None:
。)
try
/except
块没有单行语法。幸运的是,线路便宜,因此4线解决方案应该可以为您服务。;-)
get
如果您不想例外,请不要使用。使用filter
代替。
这非常骇人听闻,但是当我想编写一系列调试动作时,已经在提示符下使用了它:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()"
print "The problem is %s" % problem[1]
在大多数情况下,我完全不受no-single-line-try-except限制的困扰,但是当我只是做实验时,我希望readline在交互式解释器中一次调用全部代码,因此我可以以某种方式调整它,这个小技巧很有用。
对于您要实现的实际目的,您可以尝试locals().get('c', b)
;理想情况下,最好使用真实的字典而不是本地上下文,或者只在运行可能设置或未设置它之前将c分配给None。
problem[0]
返回该函数返回的内容?
在python3中,您可以使用contextlib.suppress:
from contextlib import suppress
d = {}
with suppress(KeyError): d['foo']
另一种方法是定义上下文管理器:
class trialContextManager:
def __enter__(self): pass
def __exit__(self, *args): return True
trial = trialContextManager()
然后使用该with
语句在一行中忽略错误:
>>> with trial: a = 5 # will be executed normally
>>> with trial: a = 1 / 0 # will be not executed and no exception is raised
>>> print a
5
如果发生运行时错误,则不会引发异常。就像try:
没有了except:
。
poke53280答案的版本,带有有限的预期例外。
def try_or(func, default=None, expected_exc=(Exception,)):
try:
return func()
except expected_exc:
return default
它可以用作
In [2]: try_or(lambda: 1/2, default=float('nan'))
Out[2]: 0.5
In [3]: try_or(lambda: 1/0, default=float('nan'), expected_exc=(ArithmeticError,))
Out[3]: nan
In [4]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError,))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
[your traceback here]
TypeError: unsupported operand type(s) for /: 'str' and 'int'
In [5]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError, TypeError))
Out[5]: nan
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
总有解决方案。
您可以通过访问该命名空间字典做到这一点vars()
,locals()
或者globals()
,无论哪个是最适合您的情况。
>>> b = 'some variable'
>>> a = vars().get('c', b)
如果您需要实际管理异常:(
从poke53280的答案中修改)
>>> def try_or(fn, exceptions: dict = {}):
try:
return fn()
except Exception as ei:
for e in ei.__class__.__mro__[:-1]:
if e in exceptions: return exceptions[e]()
else:
raise
>>> def context():
return 1 + None
>>> try_or( context, {TypeError: lambda: print('TypeError exception')} )
TypeError exception
>>>
请注意,如果不支持该异常,它将按预期引发:
>>> try_or( context, {ValueError: lambda: print('ValueError exception')} )
Traceback (most recent call last):
File "<pyshell#57>", line 1, in <module>
try_or( context, {ValueError: lambda: print('ValueError exception')} )
File "<pyshell#38>", line 3, in try_or
return fn()
File "<pyshell#56>", line 2, in context
return 1 + None
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
>>>
如果Exception
给出,它将与下面的任何内容匹配。
(BaseException
更高,因此将不匹配)
>>> try_or( context, {Exception: lambda: print('exception')} )
exception