2010-06-15 3 views
1

У меня есть метод, который либо вернет объект, либо None, если сбой поиска. Какой стиль следующего лучше?Какой стиль возврата «лучше» для метода, который может вернуть None?

def get_foo(needle): 
    haystack = object_dict() 
    if needle not in haystack: return None 
    return haystack[needle] 

или

def get_foo(needle): 
    haystack = object_dict() 
    try: 
     return haystack[needle] 
    except KeyError: 
     # Needle not found 
     return None 

Я не определились, какие еще более желанной себе. Другим выбором будет return haystack[needle] if needle in haystack else None, но я не уверен, что это лучше.

+0

Если это действительно было отмечено wiki сообщества? – detly

+0

Я думал, что это правильный способ сделать что-то для «субъективных» сообщений. Это неправильно? – Daenyth

+0

Хороший вопрос. Я не уверен, где линия сама :) – detly

ответ

10

Для этого конкретного примера, это выглядит как dict метод get является самым кратким:

def get_foo(needle): 
    haystack = object_dict() 
    return haystack.get(needle) 

В общем, в Python, люди, как правило, предпочитают попробовать/за исключением того, чтобы проверить что-то первое - увидеть EAFP запись в glossary. Обратите внимание, что многие функции «тест для членства» используют исключения за кулисами.

Я не буду начинать flamewar на относительных преимуществах нескольких возвращений или альтернатив :)

+0

Заглавная запись, которую вы упомянули, является тем, что вызвало этот вопрос, в основном. Спасибо за информацию о dict.get(), я не знал, что так хорошо справляется с этой ситуацией. – Daenyth

+1

Это обычная задача - см. Также [defaultdict objects] (http://docs.python.org/library/collections.html#defaultdict-objects). Что касается EAFP, то не все следуют за ним, но стоит знать, что такое общие соглашения. Я виноват в том, что я игнорирую это сам, когда считаю, что это уместно. – detly

2

если оба делают точно то же самое, выбрать тот, который вам нравится больше всего и то более удобным для чтения - я, как второй, но оба хороши.

(может быть один, если это быстрее, чем другой - так что если Палатки является действительно важно, протестировать и выбрать один быстрее)

+1

Как вы можете сказать «оба хороши»? Первый выполняет поиск дважды каждый раз, когда он вызывается: один раз, чтобы узнать, есть ли ключ, затем снова, чтобы получить и вернуть значение. Это просто кажется мне немым. –

+0

@ Don: Это отличный момент, который я даже не рассматривал. – Daenyth

-2

В каждом языке, который я использовал первый вариант является perferable. Исключения в основном скрыты у многих из тех же проблем, поэтому я не использую их, если я могу избежать этого.

Существует также возможная стоимость исполнения. Я не знаю о Python, но на многих других языках существует большая стоимость для создания исключения, которое вы собираетесь выбросить на следующей строке.

+3

КАЖДАЯ структура управления - это переоформление 'goto'. Сравнение сложных и четко определенных структур управления с 'goto' бессмысленно. Кроме того, многие функции «тест для членства» используют исключения за кулисами. – detly

+0

Что касается аспекта скорости, я не профилировал, чтобы узнать, что быстрее, но моя интуиция говорит мне, что версия try/except может быть быстрее в общем случае (найдена игла). Первая версия проверит выражение if на каждом вызове, тогда как try/except будет использовать исключение только в случае сбоя. Пожалуйста, дайте мне знать, если у меня есть некоторые недоразумения в отношении внутренних элементов и того, что я только что описал. Во всяком случае, это не будет обычный звонок, поэтому он больше подходит для стиля/удобочитаемости, чем скорость. – Daenyth

+0

@detly Большинство структур управления не имеют поведения «прыгать из любого места», которое имеют исключения. Точки выхода хорошо определены в if-блоках и for-loop. Только в блоках try каждая строка эффективно становится goto. –

Смежные вопросы