En Python, j'ai réfléchi à la façon d'écrire une fonction qui évalue le court-circuit et renvoie une valeur autre que None qui est apparue pour la première fois.
Tout d'abord, à titre d'exemple, exécutez la fonction get_answer ()
qui évalue trois expressions, yahoo ()
, google ()
et ʻask () `dans l'ordre, et renvoie une valeur autre que None qui apparaît en premier. J'ai écrit get_answer.py normalement. L'opération a été confirmée avec Python 2.7.3 et Python 3.2.3.
get_answer.py
#!/usr/bin/env python
# vim:fileencoding=utf-8
from __future__ import print_function
yahoo = lambda *_: print("in yahoo()") or None
google = lambda *_: print("in google()") or 0
ask = lambda *_: print("in ask()") or "draw"
def get_answer(question):
answer = yahoo(question)
if answer is None:
answer = google(question)
if answer is None:
answer = ask("sagami", question)
return answer
if __name__ == '__main__': # pragma: nocover
print("Answer is {}.".format(get_answer("1 - 1")))
Quand tu fais ça,
in yahoo()
in google()
Answer is 0.
Est affiché. L'évaluation de google (question)
a donné une valeur autre que None, 0, donc ʻask ("sagami", question) `n'a pas été évaluée.
Si vous souhaitez que l'imbrication des instructions if soit superficielle, le nombre de lignes augmentera légèrement,
def get_answer(question):
answer = yahoo(question)
if answer is not None:
return answer
answer = google(question)
if answer is not None:
return answer
return ask("sagami", question)
Vous pouvez également écrire comme ça. Mais cette fonction
def get_answer(question):
return (yahoo(question) or
google(question) or
ask("sagami", question))
Ou
def get_answer(question):
for answer in (yahoo(question),
google(question),
ask("sagami", question)):
if answer is not None:
return answer
return None
Ne peut pas être écrit comme. Lorsque le premier est exécuté,
in yahoo()
in google()
in ask()
Answer is draw.
Et 0, qui est une valeur autre que None, sera ignoré, et lorsque ce dernier sera exécuté,
in yahoo()
in google()
in ask()
Answer is 0.
Par conséquent, même ʻask ("sagami", question) `, qui n'a pas besoin d'être évalué, sera évalué.
À la suite de divers problèmes, en utilisant le décorateur @ any
,
@anyone
def get_answer(question):
yield yahoo(question)
yield google(question)
yield ask("sagami", question)
J'ai trouvé une façon d'écrire. Le contenu de «@ any» est
def anyone(function):
def _(*args, **kwargs):
for value in function(*args, **kwargs):
if value is not None:
return value
return None
return _
est. Je pense que get_answer ()
peut être écrit simplement, mais qu'en est-il?
Je vous serais reconnaissant si vous pouviez me dire s'il existe une autre meilleure façon.
Ci-dessous, get_answer.py réécrit avec @ any
.
get_answer.py
#!/usr/bin/env python
# vim:fileencoding=utf-8
from __future__ import print_function
yahoo = lambda *_: print("in yahoo()") or None
google = lambda *_: print("in google()") or 0
ask = lambda *_: print("in ask()") or "draw"
def anyone(function):
def _(*args, **kwargs):
for value in function(*args, **kwargs):
if value is not None:
return value
return None
return _
@anyone
def get_answer(question):
yield yahoo(question)
yield google(question)
yield ask("sagami", question)
if __name__ == '__main__': # pragma: nocover
print("Answer is {}.".format(get_answer("1 - 1")))
Recommended Posts