Não há como compactar um try
/ except
block em uma única linha no Python.
Além disso, é uma coisa ruim não saber se uma variável existe no Python, como você faria em algumas outras linguagens dinâmicas. A maneira mais segura (e o estilo predominante) é definir todas as variáveis para algo. Se eles não forem definidos, defina-os como None
primeiro (ou 0
ou ''
ou algo se for mais aplicável).
Se você fazer atribuir todos os nomes que você está interessado em primeiro lugar, você tem opções.
A melhor opção é uma instrução if.
c = None
b = [1, 2]
if c is None:
a = b
else:
a = c
A opção de uma linha é uma expressão condicional.
c = None
b = [1, 2]
a = c if c is not None else b
Algumas pessoas abusam do comportamento de curto-circuito de or
para fazer isso. Isso está sujeito a erros, então nunca o uso.
c = None
b = [1, 2]
a = c or b
Considere o seguinte caso:
c = []
b = [1, 2]
a = c or b
Nesse caso, a
provavelmente deveria ser []
, mas é [1, 2]
porque []
é falso em um contexto booleano. Como há muitos valores que podem ser falsos, não uso esse or
truque. (Este é o mesmo problema que as pessoas enfrentam quando dizem if foo:
quando querem dizer if foo is not None:
).
try
/except
. Felizmente, as linhas são baratas, então a solução de 4 linhas deve funcionar para você. ;-)get
se você não quiser uma exceção. Use em seufilter
lugar.Isso é terrivelmente hackeado, mas usei-o no prompt quando queria escrever uma sequência de ações para depuração:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1]
Na maior parte do tempo, não estou nem um pouco incomodado com a restrição de não tentar uma única linha, mas quando estou apenas experimentando e quero que o readline lembre um pedaço inteiro de código de uma vez no interpretador interativo, que eu possa ajustá-lo de alguma forma, este pequeno truque é útil.
Para o propósito real que está tentando realizar, você pode tentar
locals().get('c', b)
; idealmente, seria melhor usar um dicionário real em vez do contexto local, ou apenas atribuir c a None antes de executar qualquer opção que possa ou não definir.fonte
problem[0]
devolver o que essa função retorna?Em python3, você pode usar contextlib.suppress :
from contextlib import suppress d = {} with suppress(KeyError): d['foo']
fonte
Outra maneira é definir um gerenciador de contexto:
class trialContextManager: def __enter__(self): pass def __exit__(self, *args): return True trial = trialContextManager()
Em seguida, use a
with
instrução para ignorar os erros em uma única linha:>>> 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
Nenhuma exceção será levantada no caso de um erro de tempo de execução. É como um
try:
sem oexcept:
.fonte
Versão da resposta poke53280 com exceções esperadas limitadas.
def try_or(func, default=None, expected_exc=(Exception,)): try: return func() except expected_exc: return default
e poderia ser usado como
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
fonte
(Exception)
é igual a omitir os colchetes.(Exception, )
diz ao interpretador que esta é uma tupla (algo como uma lista) com uma entrada. Neste exemplo, isso é usado, portanto,expected_exc
pode haver mais de uma exceção.parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
Sempre existe uma solução.
fonte
Use algo assim:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
Onde try_or é uma função de utilidade definida por você:
def try_or(fn, default): try: return fn() except: return default
Opcionalmente, você pode restringir os tipos de exceção aceitou
NameError
,AttributeError
etc.fonte
Que tal usar duas linhas. esta ok?
>>> try: a = 3; b= 0; c = a / b ... except : print('not possible'); print('zero division error') ... not possible zero division error
fonte
Você pode fazê-lo acessando o dict namespace usando
vars()
,locals()
ouglobals()
, consoante o que for mais adequado para sua situação.>>> b = 'some variable' >>> a = vars().get('c', b)
fonte
Você mencionou que está usando o Django. Se fizer sentido para o que você está fazendo, você pode usar:
created
será verdadeiro ou falso. Talvez isso ajude você.fonte
Funciona em Python3, inspirado em Walter Mundt
exec("try:some_problematic_thing()\nexcept:pass")
Para linhas múltiplas em uma linha
exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")
Ps: Exec não é seguro para usar em dados que você não tem controle.
fonte
se você realmente precisa gerenciar exceções:
(modificado da resposta de 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 >>>
observe que se a exceção não for suportada, ela aumentará conforme o esperado:
>>> 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' >>>
também se
Exception
for fornecido, ele corresponderá a qualquer coisa abaixo.(
BaseException
é mais alto, então não vai corresponder)>>> try_or( context, {Exception: lambda: print('exception')} ) exception
fonte
Aqui está uma versão mais simples da resposta fornecida por @surendra_ben
a = "apple" try: a.something_that_definitely_doesnt_exist except: print("nope") ... nope
fonte
Use a
with
sintaxe em uma linha: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
Ignore quaisquer erros:
with OK(): 1/0
Ignore os erros especificados:
with OK(ZeroDivisionError, NameError): 1/0
fonte