Должен ли я вернуть None или (None, None)?


у нас есть метод объекта, который возвращает кортеж города / штата, т. е. ('Boston', 'MA'). При некоторых уважительных обстоятельствах нет действительного города / штата для возвращения. Стилистически, имеет ли смысл вернуться None, или кортеж из двух элементов, содержащий (None, None) в этом случае?

9 54

9 ответов:

Я вернусь None. Если нет результата, зачем возвращать то, что выглядит как результат?

это также легче проверить:

result = getCity()
if result:
   # do something

Я бы только вернулся (None, None) если бы это было возможно, что только одно из двух значений None (т. е. ('Boston', None)). Это было бы более последовательно в данном случае.

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

city, state = getCityStateTuple("something")

в таком случае, возвращаясь None сломается абонент ошибка:

TypeError: 'NoneType' object is not iterable

Итак, я лично бы вернулся (None, None) в вашей ситуации. Опять же, ваш пробег может варьироваться, и это зависит от шаблона, используемого абонентами.

(None, None) не дает False в Python. Кроме того, построение кортежа требует больше работы, чем, ну, не построение кортежа. Так что я бы предпочел None.

как отмечали другие, кортеж с элементами в нем не тестируется как False, что является одной из причин, по которой вы можете захотеть вернуть None, а не (None, None). Однако, можно написать кортежа!--9-->подкласс что тесты False даже если он имеет элементы в нем путем переопределения его __nonzero__() метод.

class falsetuple(tuple):
    def __nonzero__(self):
        return False

тогда вы могли бы вернуться falsetuple((None, None)) когда нет доступного значения. На самом деле, вы всегда можете вернуть то же самоеfalsetuple.

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

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

Если бы это был я, и я выбрал кортеж над исключением, я бы пошел с FalseTuple, который предлагает kindall, а также понял, что вызывающий код (который использует распаковку кортежа) также может тестировать

if city is None:

чтобы увидеть, если действительный результат был получен. Таким образом, вы поддерживаете извлечение кортежа по всем возможным возвращаемым значениям и все еще позволяете питонской идиоме спрашивать объект: "вы оцениваете как истину?(Вот киндалл опять для полноты картины):

class FalseTuple(tuple):
    def __nonzero__(self):
        return False

Почему бы не сделать государственную собственность города? Так что ваша функция всегда будет возвращать одно значение: город или нет.

возврат (None, None) плох по всем причинам, указанным в других ответах, и служит только для поддержки распаковки кортежа.

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

для меня, возвращение (Нет, Нет) означает, что (нет, государство) или (город, нет) будет также допустимые возвращаемые значения. Если это так, идите с (None, None), иначе Феликс и Брент предоставляют очень хорошие аргументы для простого возврата None.

Я бы реализовал открытый метод для объекта, который возвращается, скажем isValidLocation() Это возвращает true, если location является допустимым и false, если location нет.

Если вы не возвращаете ни одного, Вам будет намного проще проверить возвращаемое значение.