Partage
  • Partager sur Facebook
  • Partager sur Twitter

Appeler une fonction à partir d'une variable

    18 septembre 2017 à 23:23:39

    Bonjour,

    Je cherche à appeler une fonction  dont le nom est contenu dans une variable.

    j'ai une variable de type string qui contient : "work.SMS.main.init"

    et je cherche à appeler la fonction init contenue dans le module main.py qui est contenu dans les packages work et SMS (work/SMS/main.py)

    Je n'ai pas trouvé de solution malgré mes recherches.
    Est ce possible en python ?

    Bon j'ai trouvé une solution avec eval mais il semble que ça ne soit pas propre, existe-t-il un autre moyen ?

    -
    Edité par Jpaul78 18 septembre 2017 à 23:35:05

    • Partager sur Facebook
    • Partager sur Twitter
    Amicalement, Jean-Paul
      18 septembre 2017 à 23:39:59

      Bonjour,

      Vous pouvez appeler la fonction via un dictionnaire (https://softwareengineering.stackexchange.com/questions/182093/why-store-a-function-inside-a-python-dictionary)

      comme par ex:

      def foo():
          return 1
      
      def bar():
          return foo()+1
      
      dico = {
          'foo': foo,
          'bar': bar,
      }
      
      a = "foo"
      dico[a] => retournera 1

      Pour passer un argument, vous trouverez des info sur https://stackoverflow.com/questions/9205081/python-is-there-a-way-to-store-a-function-in-a-list-or-dictionary-so-that-when mais il suffit de changer comme ca:

      def foo(a):
          return a+1
      
      def bar(b):
          return foo(b)+1
      
      dico = {
          'foo': foo,
          'bar': bar,
      }
      
      a = "bar"
      dico[a](4) => retournera 6 (4+1 de foo et +1 de bar)




      -
      Edité par coni63 18 septembre 2017 à 23:44:24

      • Partager sur Facebook
      • Partager sur Twitter
        19 septembre 2017 à 8:03:27

        Bonjour,

        Merci pour cette réponse.

        En fait, je cherche à faire un système qui me permette de rajouter des modules facilement.
        J'ai imaginé un fichier appelons le prog.py qui est celui qu'on lance.
        Ce fichier est contenu dans un répertoire qui contient aussi un package work.
        Dans ce dossier work on va pouvoir ajouter des sous-packages comme SMS (dans mon cas ce sera le premier package mais il y en aura d'autres)
        Par convention, pour être pris en compte, les sous-packages doivent contenir un module main.py qui dispose d'une fonction init()

        Ce que je cherchais à faire était (dans prog.py) de parcourir le dossier qui correspond au package work afin d'ajouter les modules des sous paquets.

        J'ai fini par y arriver grâce à ce forum en utilisant import_module

        Voici un le code qui illustre cela :

        L'arborescence est la suivante :

        prog.py

        ./work

        ./work/__ini__.py

        ./work/sous_sys1

        ./work/sous_sys1/main.py

        ./work/sous_sys1/__ini__.py

        le fichier prog.py :

        import os.path
        from importlib import import_module
        from glob import glob
         
        sous_systemes= []
        ld=glob(os.path.dirname(os.path.realpath(__file__))+"/work/*")
        for i in ld:
        	if  os.path.isdir(i):
        		ld2=glob(i+"/*")
        		for j in ld2:
        			if os.path.basename(j) == "main.py":
        				sous_systemes.append(import_module("work."+os.path.basename(i)+"."+os.path.splitext(os.path.basename(j))[0]))
        for i in sous_systemes:
        	i.init()
        

        le fichier main.py :

        import os.path
        def init():
        	print("This is init from : "+os.path.basename(os.path.dirname(__file__))+"\n")


        Pour avoir plusieurs sous systèmes, il suffit de recopier le répertoire sous_sys1 (et son contenu) avec un autre nom et de modifier le fichier main.py pour qu'il fasse ce que l'on désire.

        Dans le cas de cet exemple, la boucle

        for i in sous_systemes:

        du fichier prog.py n'est lue qu'une seule fois mais dans mon utilisation, j'ai placé cette partie du code dans une boucle sans fin et prog.py tourne en daemon (lancé au démarrage d'un raspberry).
        Il suffit alors defaire une copie du sous répertoire sous_sys1 et de le modifier le fichier main.py (contenu dans la copie) pour pouvoir ajouter une fonctionnalité qui sera prise en compte dès qu'on relancera le prog.py.

        encore merci :-)


        -
        Edité par Jpaul78 19 septembre 2017 à 15:06:51

        • Partager sur Facebook
        • Partager sur Twitter
        Amicalement, Jean-Paul

        Appeler une fonction à partir d'une variable

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown