En passant 'None' comme paramètre de la fonction (d'où le paramètre est une fonction)
Je suis en train d'écrire une petite application qui doit effectuer des 'hygiénique' avant d'entrer dans l'exécution. (eg. d'un sanity check: vérifier si un chemin est accessible en lecture /écriture /existe)
Le code:
import logging
import os
import shutil
import sys
from paths import PATH
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger('sf.core.sanity')
def sanity_access(path, mode):
ret = os.access(path, mode)
logfunc = log.debug if ret else log.warning
loginfo = (os.access.__name__, path, mode, ret)
logfunc('%s(\'%s\', %s)==%s' % loginfo)
return ret
def sanity_check(bool_func, true_func, false_func):
ret = bool_func()
(logfunc, execfunc) = (log.debug, true_func) if ret else \
(log.warning, false_func)
logfunc('exec: %s', execfunc.__name__)
execfunc()
def sanity_checks():
sanity_check(lambda: sanity_access(PATH['userhome'], os.F_OK), \
lambda: None, sys.exit)
Ma question est liée à la sanity_check
fonction.
Cette fonction prend 3 paramètres (bool_func
, true_func
, false_func
). Si le bool_func
(qui est la fonction de test, renvoyant une valeur booléenne) échoue, true_func
est exécuté, sinon le false_func
est exécuté.
1) lambda: None
est un peu boiteux , parce que par exemple si le sanity_access renvoie True, lambda: None
est exécuté, et la sortie imprimée sera:
DEBUG:sf.core.sanity:access('/home/nomemory', 0)==True
DEBUG:sf.core.sanity:exec: <lambda>
Afin de ne pas être très clair dans les logs de la fonction qui ont été exécutés. Le journal ne contient <lambda>
. Est-il un défaut de fonction qui ne fait rien et peut être passé en paramètre ? Est-ce une façon de retourner le nom de la première fonction qui est exécutée à l'intérieur d'un lambda ?
Ou une manière de ne pas journal "exec" si "rien" est envoyé comme un paramètre ?
Quelle est la aucun /ne-rien d'équivalent pour les fonctions ?
sanity_check(lambda: sanity_access(PATH['userhome'], os.F_OK), \
<do nothing, but show something more useful than <lambda>>, sys.exit)
Autre question, pourquoi est - lambda: pass
au lieu de lambda: None
pas de travail ?
Le "lambda chose" n'aide pas, est-il? Beaucoup de contrôles de ne pas justifier de son niveau de complexité. Pourquoi ne pas simplement utiliser
if
déclarations?Vous pourriez tout simplement essayer d'écrire le chemin d'accès et le journal, si cela échoue.
Vous essayez d'écrire lisp, python.
La programmation fonctionnelle n' pas moyen d'écrire un tas de fonctions ou de passer des fonctions de autour de! Cela signifie écrire simple, évidemment correct et réutilisables, les fonctions et les utiliser pour mettre ensemble des fonctions plus complexes. FP fonctionne très bien en Python, mais son moins sur le passage de fonctions autour de et plus sur l'utilisation de LCs, des générateurs et des itertools.
OriginalL'auteur Andrei Ciobanu | 2010-09-16
Vous devez vous connecter pour publier un commentaire.
Ce qui est avec tous les lambdas qui ne servent à rien? Eh bien, peut-être des arguments optionnels va vous aider un peu:
Mais vous êtes vraiment de compliquer à l'excès les choses.
OriginalL'auteur Jochen Ritzel
mise à jour
Normalement j'supprimer ce post car THC4k vu à travers toute la complexité et la réécriture de votre fonctionner correctement. Cependant, dans un contexte différent, le K combinator truc peut venir dans maniable, donc je vais le laisser en place.
Il n'y a pas de builtin qui fait ce que vous voulez AFIK. Je crois que vous voulez le K combinator (le lien arrive sur une autre question), ce qui peut être codé comme
bien sûr, si c'est juste un hors tension, puis vous pourriez faire
Mais alors vous ne devez pas dire "K combinator". Un autre avantage de la "K_combinator' approche est que vous pouvez passer à des fonctions, par exemple,
comme pour votre deuxième déclaration, seules les expressions sont autorisés dans
lambda
.pass
est une instruction. Par conséquent,lambda: pass
échoue.Vous pouvez légèrement simplifier votre appel à la raison vérifier en enlevant le lambda autour du premier argument.
C'est plus lisible (en grande partie par l'expansion de l'opérateur ternaire dans un si). le
boolfunc
n'a rien fait parce quesanity_check
n'était pas d'ajouter tous les arguments de l'appel. Pourrait tout aussi bien appeler à la place de l'enveloppant dans une lambda.OriginalL'auteur aaronasterling
Vous voudrez peut-être repenser.
Appelable objets peuvent simplifier votre vie.
SanityCheck
au lieu d'objets 😉Votre exemple est un bon (lisible) de rechange. Mais une chose: n'est-ce pas une sous-classe de SanityCheck assez, qui reçoit chemin / mode comme paramètre ? Une autre chose: Que si, parfois, quand not_ok() je veux faire un complètement différentes tâches au lieu de sys.exit() . Même pour ok()...
Ciobanu: Vous pouvez toujours remplacer
ok
etnot_ok
dans une sous-classe.Qui pourrait être une solution. Une programmation orientée objet.
C'est en fait plus compliqué que ce que l'OP a posté après vous bande de totalité de l'enregistrement des informations. Ou au moins de mon point de vue.
OriginalL'auteur S.Lott
AaronMcSmooth a déjà expliqué pourquoi ça ne marcherait pas. Je ne pensais pas à le reproduire et de les écrire à nouveau dans ma réponse.
OriginalL'auteur pyfunc
En fait, ce que vous voulez, c'est une fonction qui ne fait rien, mais a un
__name__
ce qui est utile pour le journal. La fonction lambda est faire exactement ce que vous voulez, maisexecfunc.__name__
est de donner"<lambda>"
. Essayez l'une de ces:Vous pouvez aussi mettre vos propres attributs sur les fonctions:
Puis changer
execfunc.__name__
àgetattr(execfunc,'log_info', '')
OriginalL'auteur greggo