python中是否有办法将try / except转为一行?
类似......
b = 'some variable'
a = c | b #try statement goes here
b
是声明的变量而c
不是......所以c
会抛出错误而a
会变成b
...
答案 0 :(得分:65)
这非常hackish,但是当我想编写一系列调试操作时,我已经在提示符下使用它了:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()"
print "The problem is %s" % problem[1]
在大多数情况下,我完全没有受到单行 - 尝试 - 除外限制的困扰,但是当我只是尝试并且我想让readline回想起整个代码块时在交互式翻译中,我可以在某种程度上调整它,这个小技巧就派上用场了。
出于实际目的,您可以尝试locals().get('c', b)
;理想情况下,最好使用真正的字典而不是本地上下文,或者在运行可能或不可能设置之前将c分配给None。
答案 1 :(得分:44)
无法在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:
时会遇到同样的问题。)
答案 2 :(得分:9)
另一种方法是定义上下文管理器:
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:
的{{1}}。
答案 3 :(得分:5)
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
始终有解决方案。
答案 4 :(得分:5)
如何使用两行。可以吗?
>>> try: a = 3; b= 0; c = a / b
... except : print('not possible'); print('zero division error')
...
not possible
zero division error
答案 5 :(得分:4)
您可以使用vars()
,locals()
或globals()
访问命名空间字典,以最适合您的情况为准。
>>> b = 'some variable'
>>> a = vars().get('c', b)
答案 6 :(得分:2)
你提到你正在使用django。如果您正在做的事情有意义,您可能想要使用:
my_instance, created = MyModel.objects.get_or_create()
created
将为真或假。也许这会对你有帮助。
答案 7 :(得分:2)
问题是它实际上是一个django model.objects.get查询我试图测试。如果没有找到数据,.get会返回错误...它不会返回None(这会让我烦恼)
使用类似的东西:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
其中try_or是您定义的实用程序函数:
def try_or(fn, default):
try:
return fn()
except:
return default
您可以选择将接受的例外类型限制为NameError
,AttributeError
等。
答案 8 :(得分:2)
受Walter Mundt启发,在Python3上工作
for event in pygame.event.get():
# Always here to make it possible to exit when pressing X in game window:
if event.type == pygame.QUIT:
self.playing = False
pygame.quit()
quit()
# Left mouse button down events:
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
pos = pygame.mouse.get_pos()
if button.collidepoint(pos):
print('do what button is supposed to do')
将多行合并为一行
exec("try:some_problematic_thing()\nexcept:pass")
Ps:Exec不安全地用于无法控制的数据。
答案 9 :(得分:1)
在python3中,您可以使用contextlib.suppress:
from contextlib import suppress
d = {}
with suppress(KeyError): d['foo']
答案 10 :(得分:1)
在一行中使用 with
语法:
class OK(): __init__ = lambda self, *isok: setattr(self, 'isok', isok); __enter__ = lambda self: None; __exit__ = lambda self, exc_type, exc_value, traceback: (True if not self.isok or issubclass(exc_type, self.isok) else None) if exc_type else None
忽略任何错误:
with OK(): 1/0
忽略指定的错误:
with OK(ZeroDivisionError, NameError): 1/0
答案 11 :(得分:0)
如果您需要实际管理例外:
(修改自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
答案 12 :(得分:0)
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
答案 13 :(得分:0)
这是@surendra_ben提供的答案的简单版本
a = "apple"
try: a.something_that_definitely_doesnt_exist
except: print("nope")
...
nope