从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+)。