Python: оператор try в одной строке
есть ли способ в python превратить try / except в одну строку?
что-то вроде...
b = 'some variable'
a = c | b #try statement goes here
здесь b является объявленной переменной и c нет... так что c выдаст ошибку и a станет b...
9 ответов:
нет никакого способа, чтобы сжать
try/exceptблок на одной строке в Python.кроме того, плохо не знать, существует ли переменная в Python, как и в некоторых других динамических языках. Более безопасный способ (и преобладающий стиль) - установить все переменные на что-то. Если они не могут быть установлены, установите их в
Noneпервый (или0или''или что-то, если это более применимо.)
если вы do присвоить все имена, которые вас интересуют в первую очередь, у вас есть варианты.
лучшим вариантом является оператор 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:.)
это ужасно hackish, но я использовал его в приглашении, когда я хотел написать последовательность действий для отладки:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1]для реальной цели вы пытаетесь выполнить, вы можете попробовать
locals().get('c', b); в идеале было бы лучше использовать реальный словарь вместо локального контекста или просто назначить c None перед запуском того, что может или не может его установить.
вы можете сделать это, обратившись к пространству имен dict с помощью
vars(),locals()илиglobals()в зависимости от того является наиболее подходящим для вашей ситуации.>>> b = 'some variable' >>> a = vars().get('c', b)
другой способ-определить контекстный менеджер:
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:.
Вы упомянули, что используете django. Если это имеет смысл для того, что вы делаете, вы можете использовать:
my_instance, created = MyModel.objects.get_or_create()
createdбудет True или False. Может быть, это вам поможет.
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)всегда есть решение.
проблема в том, что его на самом деле модель django.объекты.получить запрос, который я пытаюсь проверить. этот.get возвращает ошибку, если данные не найдены... он не возвращает ни одного (что меня раздражает)
использовать что-то вроде этого:
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и т. д.
если вам нужно, чтобы на самом деле управлять исключениями:
(изменено из ответа 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
в python3 вы можете использовать contextlib.подавить:
from contextlib import suppress d = {} with suppress(KeyError): d['foo']