2011-01-18 1 views
1

Я ищу для стандартной функции (оператор, декоратор), которая была бы эквивалентна следующей рукописной функции:Есть ли аналог этой функции в стандартных модулях Python?

def defaulted(func, defaultVal): 
    try: 
     result = func() 
    except: 
     result = defaultVal 

    return result 

Спасибо!

+1

Вы понимаете, что ['кроме:' часто злой] (http://docs.python.org/howto/doanddont.html#except)? Вы, возможно, не хотите, чтобы такая функция проглатывала синтаксические ошибки ... – delnan

+8

@delnan: Пожалуйста, прекратите увековечить миф о том, что кроме: блоков СинтаксисErrors. Если вы не динамически компилируете код (или сначала импортируете модуль внутри этого блока, что то же самое), это не так. Он блокирует достаточно реальных проблем, которые нам не нужно прибегать к гиперболе о том, насколько это плохо. –

+1

@ Joe: D'oh! Конечно, он не проглатывает SyntaxError, извините за дезинформацию. – delnan

ответ

5

Нет ничего подобного в stdlib (насколько мне известно). Во-первых, это плохая практика: вы должны никогда использовать голый except. (Вместо этого укажите исключения, которые вы хотите поймать, таким образом, вы не будете ловить все!)

Вот декоратор: философия

>>> def defaultval(error, value): 
...  def decorator(func): 
...    def defaulted(*args, **kwargs): 
...      try: 
...        return func(*args, **kwargs) 
...      except error: 
...        return value 
...    return defaulted 
...  return decorator 
... 
>>> @defaultval(NameError, "undefined") 
... def get_var(): 
...  return name 
... 
>>> get_var() 
'undefined' 
+0

Мне это нравится, очень приятно! –

3

№ п.п. Python является то, что явно лучше, чем неявное. Большинство функций Python, которые являются , ожидали, чтобы регулярно генерировать исключения, например dict .__ getitem__, предоставлять эквивалентные версии, которые возвращают значение по умолчанию, например dict.get.

Я использовал новое с контекстами для чего-то подобного раньше; код выглядел так:

with ignoring(IOError, OSError): 
    # some non-critical file operations 

Но мне тоже ничего не нужно было возвращать. Как правило, уровень всей функции - это плохое место для этого, и, используя декораторы, вы блокируете любую возможность при получении ошибки, если хотите, чтобы вы ее обработали более грациозно в другом месте.

Также, except: чрезвычайно опасен; вы, вероятно, имеете в виду (по крайней мере) except Exception: и, вероятно, что-то еще более плотное, например IOError или KeyError. В противном случае вы также поймаете такие вещи, как Ctrl-C, SystemExit и имена с ошибками.