Ответ 1
Предоставление имени результата вызова func1 относительно дешево, поэтому я бы сделал это, но напишу функцию следующим образом:
def func2(n):
ret = func1(n)
return ret if ret is not None else something_else
Скажем, у меня есть 2 функции. Я хочу func2 вернуть func1 UNLESS func1 возвращает None, и в этом случае func2 возвращает что-то еще. Есть два способа сделать это, но они оба чувствуют себя немного неправильно.
Я мог бы сказать:
def func1(n):
if (condition):
return foo
def func2(n):
if func1(n) is not None:
return func1(n)
else:
return something_else
Но это кажется неправильным, потому что я должен дважды вызвать func1 (n) (а func1 (n) - более крупное вычисление). Чтобы обойти это, я мог бы сказать:
def func1(n):
if (condition):
return foo
def func2(n):
foo = func1(n)
if foo is not None:
return foo
else:
return something_else
но это кажется неправильным, потому что я не думаю, что мне нужно будет назначить новую переменную, которая никогда не будет использоваться снова, просто чтобы проверить, вернул ли func1 None.
Есть ли более простой способ сделать это, когда мне не нужно дважды звонить func1, и мне не нужно создавать новую переменную? Если это единственный способ, какой из двух вы бы порекомендовали? В настоящее время я использую его вторым способом (где я устанавливаю foo для возвращаемого func1, чем возвращает foo, если foo == None)
Кроме того, имейте в виду, что в моем реальном коде я вызываю несколько разных функций, и я хочу вернуть первый, который не является None, это просто более простая версия кода, которая задает вопрос.
Предоставление имени результата вызова func1 относительно дешево, поэтому я бы сделал это, но напишу функцию следующим образом:
def func2(n):
ret = func1(n)
return ret if ret is not None else something_else
Так как None
оценивается как False
, вы можете сделать:
def func2(n):
return func1(n) or something_else
Следует отметить, однако, что это приведет к возврату func2
something_else
, если func1(n)
возвращает что-либо ложное (0
, []
и т.д.)
Для многих функций вы можете использовать next
и некоторый генератор выражения:
def myfunc(n):
vals = (f(n) for f in (func1, func2, func3...))
return next((v for v in vals if v is not None), something_else)
Вы определенно не хотите дважды звонить func1
, а также быть неэффективными, func1
может иметь побочные эффекты или давать немного другой ответ в зависимости от состояния в то время.
Кроме того, нет необходимости в else
после return
, когда return
вышел из функции.
Пересмотренная версия вашего второго варианта будет:
def func1(n):
if condition:
return foo
def func2(n):
foo = func1(n)
if foo is None:
return something_else
return foo
Обратите внимание, что это работает, даже если функция func1 возвращает значение false.
В качестве альтернативы, отметив содержимое func1
, вы могли бы сделать:
def func1(n):
return foo
def func2(n):
foo = func1(n)
if condition:
return foo
return something_else
Это зависит от того, каков реальный контент func1
.
Как совершенно другой подход из моего предыдущего ответа, основанный на вашем комментарии к iCodez:
def func1(n):
return ham
def func2(n):
return jam
def func3(n):
return spam
def mainfunc(n):
for f in (func1, func2, func3):
foo = f(n)
if foo is not None:
return foo