Python --Fonction d'appel dynamique à partir d'une chaîne

Comment appeler dynamiquement une fonction à partir d'une chaîne en Python

Il y avait quelques explications sur les appels dynamiques aux méthodes et propriétés, Je ne savais pas comment appeler dynamiquement des fonctions et des variables globales, alors j'ai cherché.

eval() Lorsque vous exécutez eval (), la chaîne passée en argument est évaluée en tant que code Python. Vous pouvez l'utiliser pour appeler n'importe quelle fonction ou valeur de variable à partir d'une chaîne.

Documentation officielle http://docs.python.jp/3.5/library/functions.html#eval

Je l'utilise comme ça

eval_test.py


def func():
    print('func() is called')

global_val = 'this is global'

#Fonction globale normale, appel de variable
func()
print(global_val)

#Fonction globale, appel de variable à partir d'une chaîne de caractères
eval('func')()
print(eval('global_val'))

Résultat d'exécution


$ python eval_test.py 
func() is called
this is global
func() is called
this is global

Tu peux tout faire avec ça

globals()

Vous pouvez obtenir le dictionnaire des fonctions et des variables définies dans la portée globale en appelant la fonction intégrée globals ().

Documentation officielle http://docs.python.jp/3.5/library/functions.html#globals

Je l'utilise comme ça

function_call_test.py


def func():
    print('func() is called')
    #Mondiaux à portée locale()
    print(globals())

global_val = 'this is global'

#Mondiaux à portée mondiale()
print(globals())

#Fonction globale normale, appel de variable
func()
print(global_val)

#Fonction globale, appel de variable à partir d'une chaîne de caractères
globals()['func']()
print(globals()['global_val'])

Résultat d'exécution


$ python function_call_test.py 
{'global_val': 'this is global', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b185828>, '__name__': '__main__', '__package__': None, '__doc__': None, '__cached__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, 'func': <function func at 0x10b186950>, '__file__': 'function_call_test.py'}
func() is called
{'global_val': 'this is global', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b185828>, '__name__': '__main__', '__package__': None, '__doc__': None, '__cached__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, 'func': <function func at 0x10b186950>, '__file__': 'function_call_test.py'}
this is global
func() is called
{'global_val': 'this is global', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b185828>, '__name__': '__main__', '__package__': None, '__doc__': None, 'func_name': 'func', '__cached__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, 'func': <function func at 0x10b186950>, '__file__': 'function_call_test.py'}
this is global

Vous pouvez appeler à la fois des fonctions globales et des variables globales sous forme de chaînes. Vous pouvez également voir que le résultat de globals () est le même que vous l'appeliez à partir de la portée globale ou de la portée locale.

locals()

Contrairement à globals (), locals () peut obtenir le dictionnaire des fonctions et des variables définies dans la portée locale.

Documentation officielle http://docs.python.jp/3.5/library/functions.html#locals

local_function_call_test.py


def func():
    def local_func():
        print('local_func() is called')

    print('func() is called')
    local_val = 'this is local'

    #Locaux à portée locale()
    print(locals())

    #Fonction locale normale, appel de variable
    local_func()
    print(local_val)

    #Fonction globale, appel de variable à partir d'une chaîne de caractères
    locals()['local_func']()
    print(locals()['local_val'])


#Locaux dans le monde()
print(locals())
func()

Résultat d'exécution


$ python local_function_call_test.py 
{'__name__': '__main__', '__spec__': None, '__cached__': None, '__doc__': None, '__builtins__': <module 'builtins' (built-in)>, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x1034bc208>, '__package__': None, 'func': <function func at 0x1034b2950>, '__file__': 'local_function_call_test.py'}
func() is called
{'local_val': 'this is local', 'local_func': <function func.<locals>.local_func at 0x10356c620>}
local_func() is called
this is local
local_func() is called
this is local

Les fonctions locales et les variables locales peuvent être appelées sous forme de chaînes. Cependant, contrairement à globals (), vous pouvez voir que le contenu de locals () change en fonction du bloc appelé.

(Référence) Appel dynamique des classes, méthodes et propriétés

Il est résumé dans l'article suivant

・ Réflexion en Python http://qiita.com/icoxfog417/items/bf04966d4e9706eb9e04

・ Introduction à la magie noire avec Python http://www.slideshare.net/ssuser38b704/ll-lang-blackmagic

Résumé

Il semble qu'il puisse être utilisé pour vérifier les fonctions et les variables qui sont activées dans cette portée. D'après ce que je peux voir dans la documentation, globals () semble être déterminé statiquement

En premier lieu, je ne sais pas si cela sera nécessaire à moins que ce ne soit un framework etc ... La métaprogrammation est une mise en garde contre les abus car elle rend difficile la compréhension

Recommended Posts

Python --Fonction d'appel dynamique à partir d'une chaîne
Comment créer un objet fonction à partir d'une chaîne
Comment appeler une fonction
[Python] Comment appeler une fonction de c depuis python (édition ctypes)
Créez un Dataframe pandas à partir d'une chaîne.
# 5 [python3] Extraire des caractères d'une chaîne de caractères
Générer une classe à partir d'une chaîne en Python
Appeler des commandes depuis Python (édition Windows)
Appel de scripts Python à partir de Python intégré en C ++ / C ++
Créer un objet datetime à partir d'une chaîne en Python (Python 3.3)
[Go] Comment écrire ou appeler une fonction
dlopen () ltrace un appel de fonction dans une bibliothèque partagée
[Python] J'ai essayé d'obtenir le nom du type sous forme de chaîne de caractères à partir de la fonction type
Différencier une fonction à deux variables
#Une fonction qui renvoie le code de caractère d'une chaîne de caractères
Une note sur __call__
Envisagez la conversion de Python récursif en non récursif
Appelez Rust de Python pour accélérer! Tutoriel PyO3: Emballage d'une partie de fonction simple ➁
Python> Lire à partir d'une chaîne multiligne au lieu d'un fichier> io.StringIO ()
Appeler CPLEX depuis Python (DO cplex)
Créer une fonction en Python
Ecrire une fonction de densité du noyau
Cette chaîne est-elle une fraction?
Essayez de dessiner une fonction logistique
Qu'est-ce qu'un appel système
Qu'est-ce qu'une fonction de rappel?
Créer une instance d'une classe prédéfinie à partir d'une chaîne en Python
[Road to Intermediate Python] Appelez une instance de classe comme une fonction avec __call__
[Introduction à Python] Comment fractionner une chaîne de caractères avec la fonction split
Comment obtenir une chaîne à partir d'un argument de ligne de commande en python
Comment extraire la chaîne de caractères souhaitée à partir d'une ligne 4 commandes
Appelez dlm depuis python pour exécuter un modèle de régression à coefficient variable dans le temps