128 votes

Importer dynamiquement une méthode dans un fichier, à partir d'une chaîne de caractères

J'ai une chaîne, disons : abc.def.ghi.jkl.myfile.mymethod . Comment importer dynamiquement mymethod ?

Voici comment je m'y suis pris :

def get_method_from_file(full_path):
    if len(full_path) == 1:
        return map(__import__,[full_path[0]])[0]
    return getattr(get_method_from_file(full_path[:-1]),full_path[-1])

if __name__=='__main__':
    print get_method_from_file('abc.def.ghi.jkl.myfile.mymethod'.split('.'))

Je me demande si l'importation de modules individuels est vraiment nécessaire.

Modification : j'utilise la version 2.6.5 de Python.

2voto

kingaj Points 31

Ce site web propose une solution intéressante : classe de chargement . Je l'utilise comme ça :

foo = load_class(package.subpackage.FooClass)()
type(foo) # returns FooClass

Comme demandé, voici le code du lien web :

import importlib

def load_class(full_class_string):
    """
    dynamically load a class from a string
    """

    class_data = full_class_string.split(".")
    module_path = ".".join(class_data[:-1])
    class_str = class_data[-1]

    module = importlib.import_module(module_path)
    # Finally, we retrieve the Class
    return getattr(module, class_str)

-1voto

Daniel Roseman Points 199743

Utilisez importlib (2.7+ seulement).

-1voto

Kris Hardy Points 500

La façon dont je procède (ainsi que pour un certain nombre d'autres bibliothèques, telles que pylons et paste, si ma mémoire est bonne) est de séparer le nom du module du nom de la fonction/attribut en utilisant un ':' entre les deux. Voir l'exemple suivant :

'abc.def.ghi.jkl.myfile:mymethod'

Cela rend le import_from(path) ci-dessous un peu plus facile à utiliser.

def import_from(path):
    """
    Import an attribute, function or class from a module.
    :attr path: A path descriptor in the form of 'pkg.module.submodule:attribute'
    :type path: str
    """
    path_parts = path.split(':')
    if len(path_parts) < 2:
        raise ImportError("path must be in the form of pkg.module.submodule:attribute")
    module = __import__(path_parts[0], fromlist=path_parts[1])
    return getattr(module, path_parts[1])

if __name__=='__main__':
    func = import_from('a.b.c.d.myfile:mymethod')
    func()

-1voto

Aymen Alsaadi Points 139

Que pensez-vous de ceci :

def import_module(name):

    mod = __import__(name)
    for s in name.split('.')[1:]:
        mod = getattr(mod, s)
    return mod

Prograide.com

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.

Powered by:

X