Comment appeler une fonction en utilisant une chaîne avec le nom de la fonction? Par exemple:
import foo
nom_func = "bar"
appel(foo, nom_func) # appelle foo.bar()
Comment appeler une fonction en utilisant une chaîne avec le nom de la fonction? Par exemple:
import foo
nom_func = "bar"
appel(foo, nom_func) # appelle foo.bar()
Étant donné un module foo
avec la méthode bar
:
import foo
bar = getattr(foo, 'bar')
result = bar()
getattr
peut également être utilisé sur des méthodes liées à des instances de classe, des méthodes au niveau du module, des méthodes de classe... la liste est longue.
Hasattr ou getattr peut être utilisé pour déterminer si une fonction est définie. J'avais un mappage de base de données (type d'événement et fonction de traitement) et je voulais m'assurer de ne jamais "oublier" de définir un gestionnaire d'événements dans mon Python
Cela fonctionne si vous connaissez déjà le nom du module. Cependant, si vous voulez que l'utilisateur fournisse le nom du module en tant que chaîne de caractères, cela ne fonctionnera pas.
Si vous avez besoin d'éviter une exception NoneType is not callable, vous pourriez également utiliser la forme à trois arguments de getattr: getattr(foo, 'bar', lambda: None). Je m'excuse pour la mise en forme; l'application Android de stackexchange est apparemment terrible.
Cette méthode avec globals/locals est bonne si la méthode que vous devez appeler est définie dans le même module à partir duquel vous appelez.
@Joelmob y a-t-il un autre moyen d'obtenir un objet par chaîne hors de l'espace de noms racine?
@NickT Je ne connais que ces méthodes, je ne pense pas qu'il y en ait d'autres qui remplissent la même fonction que celles-ci, du moins je ne vois pas pourquoi il devrait y en avoir plus.
Basé sur la solution de Patrick, pour obtenir le module de manière dynamique également, importez-le en utilisant :
module = __import__('foo')
func = getattr(module, 'bar')
func()
Je ne comprends pas ce dernier commentaire. __import__ a ses propres droits et la phrase suivante dans les documents mentionnés dit : "L'utilisation directe de __import__() est rare, sauf dans les cas où vous souhaitez importer un module dont le nom n'est connu qu'à l'exécution". Donc : +1 pour la réponse donnée.
Utilisez importlib.import_module
. Les documents officiels disent à propos de __import__
: "Il s'agit d'une fonction avancée qui n'est pas nécessaire dans la programmation Python quotidienne, contrairement à importlib.import_module()." docs.python.org/2/library/functions.html#__import__
@glarrain Tant que vous êtes d'accord avec le fait de ne prendre en charge que la version 2.7 et plus.
Juste une simple contribution. Si la classe que nous devons instancier se trouve dans le même fichier, nous pouvons utiliser quelque chose comme ceci :
# Obtenir la classe des globaux et créer une instance
m = globals()['our_class']()
# Obtenir la fonction (de l'instance) que nous devons appeler
func = getattr(m, 'function_name')
# Appeler la
func()
Par exemple :
class A:
def __init__(self):
pass
def sampleFunc(self, arg):
print('vous avez appelé sampleFunc({})'.format(arg))
m = globals()['A']()
func = getattr(m, 'sampleFunc')
func('argument d'échantillon')
# Exemple, tout sur une seule ligne
getattr(globals()['A'](), 'sampleFunc')('argument d'échantillon')
Et, si ce n'est pas une classe :
def sampleFunc(arg):
print('vous avez appelé sampleFunc({})'.format(arg))
globals()['sampleFunc']('argument d'échantillon')
Étant donné une chaîne de caractères, avec un chemin python complet vers une fonction, voici comment j'ai procédé pour obtenir le résultat de ladite fonction :
import importlib
function_string = 'mypackage.mymodule.myfunc'
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
result = func()
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
En utilisant eval susciterait probablement certaines inquiétudes en matière de sécurité !
0 votes
Rappel : la fonctionnalité du langage d'accéder aux champs, aux classes et aux méthodes par des noms dynamiques est appelée réflexion. Cela pourrait rendre les futures recherches plus faciles.