Explication détaillée de l'utilisation du code pour créer dynamiquement des instances de classe en Python

高洛峰
Libérer: 2017-03-26 10:07:53
original
1674 Les gens l'ont consulté

En Java, nous pouvons créer des instances de classe basées sur des noms de classe par réflexion, alors comment pouvons-nous obtenir des fonctions similaires en Python ? En fait, il existe une fonction d'importation intégrée à Python Nous pouvons utiliser cette fonction pour charger dynamiquement certains modules au moment de l'exécution

Introduction

In. Java Nous pouvons créer des instances de classe basées sur les noms de classe par réflexion, alors comment obtenir des fonctions similaires en Python ?

En fait, il existe une fonction d'importation intégrée à Python Nous pouvons utiliser cette fonction pour charger dynamiquement certains modules au moment de l'exécution. Comme suit :


def createInstance(module_name, class_name, *args, **kwargs):
  module_meta = __import__(module_name, globals(), locals(), [class_name])
  class_meta = getattr(module_meta, class_name)
  obj = class_meta(*args, **kwargs)
  return obj
Copier après la connexion

Exemple

Nous créons d'abord un répertoire my_modules, qui comprend trois fichiers

* init.py : Fichier de module
* my_module.py : module pour tester
* my_another_module : un autre module pour tester

my_module.py


from my_modules.my_another_module import *
class MyObject(object):
  def test(self):
    print 'MyObject.test'
    MyObject1().test()
    MyObject2().test()
    MyAnotherObject().test()
class MyObject1(object):
  def test(self):
    print 'MyObject1.test'
class MyObject2(object):
  def test(self):
    print 'MyObject2.test'
Copier après la connexion

my_another_module.py


class MyAnotherObject(object):
  def test(self):
    print 'MyAnotherObject.test'
Copier après la connexion

test.py


def createInstance(module_name, class_name, *args, **kwargs):
  module_meta = __import__(module_name, globals(), locals(), [class_name])
  class_meta = getattr(module_meta, class_name)
  obj = class_meta(*args, **kwargs)
  return obj
obj = createInstance("my_modules.my_module", "MyObject")
obj.test()
MyObject.test
MyObject1.test
MyObject2.test
MyAnotherObject.test
Copier après la connexion

Intégration de pyinstaller

Pour les applications packagées à l'aide de pyinstaller, si vous utilisez le code ci-dessus, après avoir exécuté le package L'erreur suivante apparaîtra dans le programme


Traceback (most recent call last):
 File "test.py", line 12, in <module>
  obj = createInstance("my_modules.my_module", "MyObject")
 File "test.py", line 7, in createInstance
  module_meta = __import__(module_name, globals(), locals(), [class_name])
ImportError: No module named my_modules.my_module
Failed to execute script test
Copier après la connexion

La raison de l'erreur ici est que pyinstaller n'a pas analysé les modules sous my_modules lors de l'empaquetage de la classe d'analyse, donc une erreur a été signalée lors de la course.

Solution 1 :

Importez manuellement le module sous my_modules dans test.py, voir la première ligne du code ci-dessous. Cette méthode est la plus simple, mais évidemment pas très bonne.


import my_modules.my_module
def createInstance(module_name, class_name, *args, **kwargs):
  module_meta = __import__(module_name, globals(), locals(), [class_name])
  class_meta = getattr(module_meta, class_name)
  obj = class_meta(*args, **kwargs)
  return obj
obj = createInstance("my_modules.my_module", "MyObject")
obj.test()
Copier après la connexion

Solution 2 :

Lorsque vous utilisez pyinstaller pour empaqueter, spécifiez "– caché- import", comme suit


pyinstaller -D --hidden-import my_modules.my_module test.py
Copier après la connexion

Solution 3 :

Modification dynamique de l'exécution de python Quand en ce qui concerne le chemin, voir les deux premières lignes du code ci-dessous, où nous pouvons transmettre le chemin via des variables d'environnement ou des paramètres. Cette méthode est évidemment beaucoup plus flexible que les deux premières méthodes.


import sys
sys.path.append(...)
def createInstance(module_name, class_name, *args, **kwargs):
  module_meta = __import__(module_name, globals(), locals(), [class_name])
  class_meta = getattr(module_meta, class_name)
  obj = class_meta(*args, **kwargs)
  return obj
obj = createInstance("my_modules.my_module", "MyObject")
obj.test()
Copier après la connexion

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:php.cn
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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!