Question

ceci est à partir du code source de csv2rec dans matplotlib

Comment ce travail de fonction, si ses paramètres sont seulement «Func, par défaut?

def with_default_value(func, default):
    def newfunc(name, val):
        if ismissing(name, val):
            return default
        else:
            return func(val)
    return newfunc

IsMissing prend un nom et une valeur et détermine si la ligne doit être masquée dans une matrice numpy.

func sera soit str, int, float, ou dateparser ... il convertit les données. Peut-être pas important. Je me demande comment il peut obtenir un « nom » et une « valeur »

Je suis un débutant. Merci pour tout 2cents! J'espère obtenir assez bon pour aider les autres!

Était-ce utile?

La solution

Cette fonction with_default_value est ce qui est souvent appelé (imprécisément) comme une « fermeture » (techniquement, la fermeture est plutôt le interne fonction qui est renvoyée, ici newfunc - voir par exemple ici ). De façon plus générique, with_default_value est fonction d'ordre supérieur ( "HOF"). Il prend une fonction (func) comme argument, elle renvoie également une fonction (newfunc) que le résultat

Je l'ai vu des réponses confonds avec le décorateur concept et construis en Python, ce qui est certainement pas le cas - d'autant plus que vous mentionnez func aussi souvent être un intégré tels que int. Les décorateurs sont également des fonctions d'ordre supérieur, mais ceux assez spécifiques: celles qui renvoient une décoration, soit « enrichi », version de leur argument de la fonction (qui doit être que Argument - « décorateurs avec des arguments » sont obtenues par un niveau plus de la fonction / fermeture de nidification, pas en donnant le décorateur HOF plus d'un argument), qui obtient réaffecté exactement le même nom que cet argument de la fonction (et a donc généralement le même signature -. au moyen d'un décorateur serait autrement très particulier, non idiomatiques, illisible, etc)

Alors oubliez les décorateurs qui ont absolument rien à voir avec le cas, et se concentrer sur la fermeture de newfunc. Une fonction lexicalement imbriquée peut se référer à (mais pas redéfinissez) tous les noms de variables locales (y compris les noms d'argument, étant donné que les arguments sont des variables locales) de la fonction englobante (s) - c'est la raison pour laquelle il est connu comme une fermeture: il est « fermé sur » ces "variables libres". Ici, newfunc peut se référer à func et default -. Et fait

Fonctions d'ordre supérieur sont une chose très naturelle en Python, d'autant plus que les fonctions sont des objets de première classe (donc il vous a rien de spécial qu'il faut faire pour les transmettre comme arguments, les renvoyer sous forme de valeurs de fonction, ou même de les stocker dans des listes ou d'autres conteneurs, etc.), et il n'y a pas de distinction d'espace de noms entre les fonctions et d'autres types d'objets, pas d'appel automatique des fonctions simplement parce qu'ils sont mentionnés, etc, etc. (Il est plus difficile - un peu plus difficile, ou beaucoup plus difficile, selon - dans d'autres langues qui font tirer beaucoup de distinctions de ce genre). En Python, en mentionnant une fonction est juste que - une mention; CALL ne se produit que si et lorsque l'objet de la fonction (appelée par son nom, ou autre) est suivie entre parenthèses.

C'est tout ce qu'il ya à cet exemple - s'il vous plaît ne hésitez pas à modifier votre question, commentaire ici, etc, s'il y a un autre aspect spécifique que vous restez dans le doute sur

Modifier : si l'OP a commenté demander courtoisement plus d'exemples de "usines de fermeture". Voici un - imaginez un peu abstrait genre de boîte à outils graphique, et vous essayez de le faire:

for i in range(len(buttons)):
  buttons[i].onclick(lambda: mainwin.settitle("button %d click!" % i))

mais cela ne fonctionne pas bien - i dans le lambda est en retard lié, donc au moment où un bouton est cliqué la valeur de i est toujours va être l'indice du dernier bouton , peu importe que l'on a cliqué. Il existe différentes solutions possibles, mais une usine de fermeture est une possibilité élégante:

def makeOnclick(message):
  return lambda: mainwin.settitle(message)

for i in range(len(buttons)):
  buttons[i].onclick(makeOnClick("button %d click!" % i))

Ici, nous utilisons l'usine de fermeture pour ajuster le temps des variables de liaison -.) Dans une forme spécifique ou d'une autre, cela est un cas d'utilisation assez commun pour les usines de fermeture

Autres conseils

Ceci est un décorateur Python - essentiellement une enveloppe de fonction. (Lire à propos de décorateurs en PEP 318 - http://www.python.org / dev / peps / pep-0318 / )

Si vous regardez à travers le code, vous trouverez probablement quelque chose comme ceci:

def some_func(name, val):
    # ...
some_func = with_default_value(some_func, 'the_default_value')

L'intention de ce décorateur semble fournir une valeur par défaut si l'les arguments nom ou val manquent (vraisemblablement, si elles sont réglées sur None).

Quant à savoir pourquoi cela fonctionne:

with_default_value retourne un objet de fonction, qui va essentiellement être Copier de cette newfunc imbriquée, avec l'appel « func » et valeur par défaut substited avec tout ce qui était passé à with_default_value.

Si quelqu'un 'foo = with_default_value (bar, 3)', la valeur de retour va essentiellement être une nouvelle fonction:

def foo(name, val):
    ifismissing(name, val):
        return 3
    else:
        return bar(val)

vous pouvez alors prendre cette valeur de retour, et l'appeler.

Ceci est une fonction qui retourne une autre fonction. name et value sont les paramètres de la fonction retournée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top