从string中dynamic地导入文件中的方法

我有一个string,说: abc.def.ghi.jkl.myfile.mymethod 。 我如何dynamic导入mymethod

这是我如何去做的:

 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('.')) 

我想知道是否需要导入个人模块。

编辑:我正在使用Python版本2.6.5。

从Python 2.7中,您可以使用importlib.import_module()函数。 您可以使用以下代码导入模块并访问其中定义的对象:

 from importlib import import_module p, m = name.rsplit('.', 1) mod = import_module(p) met = getattr(mod, m) met() 

您不需要导入各个模块。 只需导入要从中导入名称的模块并提供fromlist参数即可:

 def import_from(module, name): module = __import__(module, fromlist=[name]) return getattr(module, name) 

对于你的例子abc.def.ghi.jkl.myfile.mymethod ,调用这个函数

 import_from("abc.def.ghi.jkl.myfile", "mymethod") 

(请注意,模块级函数在Python中被称为函数,而不是方法。)

对于这样一个简单的任务,使用importlib模块没有任何优势。

对于Python <2.7,可以使用内build方法__ import__ :

 __import__('abc.def.ghi.jkl.myfile.mymethod', fromlist=['']) 

对于Python> = 2.7或3.1,添加了方便的方法importlib.import_module 。 只需像这样导入你的模块:

 importlib.import_module('abc.def.ghi.jkl.myfile.mymethod') 

更新 :根据注释更新版本( 我必须承认,我没有读到要导入的string,直到最后,我错过了一个模块的方法应该导入,而不是模块本身)的事实

Python <2.7:

 mymethod = getattr(__import__("abc.def.ghi.jkl.myfile", fromlist=["mymethod"])) 

Python> = 2.7:

 mymethod = getattr(importlib.import_module("abc.def.ghi.jkl.myfile"), "mymethod") 

目前还不清楚你想对你的本地命名空间做什么。 我假设你只想my_method作为本地,inputoutput = my_method()

 # This is equivalent to "from abmyfile import my_method" the_module = importlib.import_module("abmyfile") same_module = __import__("abmyfile") # import_module() and __input__() only return modules my_method = getattr(the_module, "my_method") # or, more concisely, my_method = getattr(__import__("abmyfile"), "my_method") output = my_method() 

虽然只能将my_method添加到本地名称空间,但您确实要加载模块链。 您可以通过在导入之前和之后查看sys.modules的键来查看更改。 我希望这比你的其他答案更清晰,更准确。

为了完整性,这是你如何添加整个链。

 # This is equivalent to "import abmyfile" a = __import__("abmyfile") also_a = importlib.import_module("abmyfile") output = abmyfile.my_method() # This is equivalent to "from ab import myfile" myfile = __import__("abmyfile", fromlist="ab") also_myfile = importlib.import_module("abmyfile", "ab") output = myfile.my_method() 

最后,如果您正在使用__import__()并在程序启动后修改了searchpath,则可能需要使用__import__(normal args, globals=globals(), locals=locals()) 。 为什么是一个复杂的讨论。

我倾向于这个方式(以及一些其他库,如塔和粘贴,如果我的记忆正确地服务我)是通过使用它们之间的“:”来将模块名称与function/属性名称分开。 看下面的例子:

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

这使得下面的import_from(path)函数更容易使用。

 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('abcdmyfile:mymethod') func() 

这个网站有一个很好的解决scheme: load_class 。 我这样使用它:

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

使用importlib (仅限2.7+)。