Maison > développement back-end > Tutoriel Python > Introduction à la méthode de définition dynamique de fonctions en Python

Introduction à la méthode de définition dynamique de fonctions en Python

不言
Libérer: 2019-03-19 10:28:02
avant
2777 Les gens l'ont consulté

Cet article vous apporte une introduction à la méthode de définition dynamique des fonctions en Python. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Sous licence MIT

En Python, il n'existe pas de sucre syntaxique qui simplifie la définition des fonctions au moment de l'exécution. Toutefois, cela ne signifie pas que cela soit impossible ou difficile à réaliser.

from types import FunctionType

foo_code = compile('def foo(): return "bar"', "<string>", "exec")
foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")

print(foo_func())
Copier après la connexion

Sortie :

bar
Copier après la connexion

Analyse

En regardant le code ligne par ligne, vous verrez à quel point la barrière langue/interprète est fragile.

>>> from types import FunctionType
Copier après la connexion

La documentation Python ne répertorie généralement pas les fonctionnalités qui ne sont pas destinées aux classes créées manuellement (ce qui est parfaitement raisonnable). Il existe trois façons de résoudre ce problème : help(), inspect (impossible d'inspecter les méthodes intégrées) et la solution finale, qui consiste à inspecter le code source de CPython. (Recommandé : Tutoriel Python)

Dans ce cas, help() et inspect peuvent faire le travail, mais l'examen du code source réel en révélera plus sur les détails des types de données.

>>> from inspect import signature
>>> signature(FunctionType)
<Signature (code, globals, name=None, argdefs=None, closure=None)>
Copier après la connexion

1. code

est en interne un objet PyCode, qui est ouvert sur le monde extérieur en tant que types.CodeType. Les méthodes non intégrées ont un attribut __code__, qui stocke l'objet code correspondant. Les objets Types.CodeType peuvent être créés au moment de l’exécution à l’aide de la méthode compile() intégrée.

2. globales

Si une fonction fait référence à une variable qui n'est pas définie localement, mais qui est transmise en tant que paramètre, fournie par une valeur de paramètre par défaut ou fournie via un contexte de fermeture, elle recherchera dans le dictionnaire global.

La méthode intégrée globals() renvoie une référence à la table des symboles globaux du module actuel et peut donc être utilisée pour fournir un dictionnaire toujours cohérent avec l'état de la table actuelle. Il est également possible de passer dans n'importe quel autre dictionnaire (FunctionType((lambda: bar).__code__, {"bar" : "baz"}, "foo")() == "baz").

3. name (facultatif)

Contrôlez l'attribut __name__ de la fonction renvoyée. Seulement vraiment utile pour les lambdas (qui n'ont généralement pas de nom en raison de l'anonymat) et pour renommer les fonctions.

4. argdefs (facultatif)

Fournit un moyen de fournir des valeurs d'argument par défaut en passant un tuple contenant des objets de n'importe quel type (def foo(bar="baz" )). (FunctionType((lambda bar: bar).__code__, {}, "foo", (10,))() == 10).

5. fermeture (facultatif)

(ne devrait probablement pas être touchée si elle doit être exécutée dans d'autres machines virtuelles Python que CPython (PyPy, Jython,...) car cela dépend sérieusement de détails de mise en œuvre).

Un tuple d'objets cellules. Créer un objet cellule n'est pas tout à fait simple, car cela nécessite des appels aux composants internes de CPython, mais il existe une bibliothèque qui facilite la tâche : exalt (publicité sans vergogne). (Annotation : cette bibliothèque a été développée par l'auteur.)

>>> foo_code = compile('def foo(): return "bar"', "<string>", "exec")
Copier après la connexion

compile() est une méthode intégrée, elle est donc également bien documentée.

le mode exécutable est utilisé car la définition d'une fonction nécessite plusieurs instructions.

>>> foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")
Copier après la connexion

Agrége tout le contenu et attribue une fonction créée dynamiquement à une variable.

La fonction compilée par la phrase de code précédente devient la première constante de l'objet de code généré, donc pointer simplement vers foo_code n'est pas suffisant. C'est une conséquence directe du mode exécution, puisque l'objet code généré peut contenir plusieurs constantes.

>>> print(foo_func())
Copier après la connexion

Les fonctions générées dynamiquement peuvent être appelées comme les autres fonctions.

Enfin

À l'exception des expériences, il existe très peu de scénarios dans lesquels des fonctions créées dynamiquement sont nécessaires.
Jouer avec les composants internes de Python est un excellent moyen d’en apprendre davantage sur le langage.
Traversez sans effort les frontières entre interprètes et langues si vous le souhaitez.


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal