从python文档中,这是你想要的功能:
def my_import(name): components = name.split('.') mod = __import__(components[0]) for comp in components[1:]: mod = getattr(mod, comp) return mod
简单__import__
不起作用的原因是因为任何超出包字符串中第一个点的内容都是您要导入的模块的属性.因此,这样的事情是行不通的:
__import__('foo.bar.baz.qux')
你必须像这样调用上面的函数:
my_import('foo.bar.baz.qux')
或者就你的例子而言:
klass = my_import('my_package.my_module.my_class') some_object = klass()
编辑:我有点偏僻.你基本上想要做的是:
from my_package.my_module import my_class
仅当您有一个空的 fromlist时,才需要上述功能.因此,适当的调用将是这样的:
mod = __import__('my_package.my_module', fromlist=['my_class']) klass = getattr(mod, 'my_class')
如果你不想自己动手,那么pydoc
模块中有一个功能就是这样:
from pydoc import locate my_class = locate('my_package.my_module.MyClass')
这种方法优于此处列出的其他方法的优点是可以在提供的虚线路径上locate
找到任何 python对象,而不仅仅是模块中直接的对象.例如my_package.my_module.MyClass.attr
.
如果你很好奇他们的食谱是什么,这里的功能是:
def locate(path, forceload=0): """Locate an object by name or dotted path, importing as necessary.""" parts = [part for part in split(path, '.') if part] module, n = None, 0 while n < len(parts): nextmodule = safeimport(join(parts[:n+1], '.'), forceload) if nextmodule: module, n = nextmodule, n + 1 else: break if module: object = module else: object = __builtin__ for part in parts[n:]: try: object = getattr(object, part) except AttributeError: return None return object
它依赖于pydoc.safeimport
功能.以下是有关的文档:
"""Import a module; handle errors; return None if the module isn't found. If the module *is* found but an exception occurs, it's wrapped in an ErrorDuringImport exception and reraised. Unlike __import__, if a package path is specified, the module at the end of the path is returned, not the package at the beginning. If the optional 'forceload' argument is 1, we reload the module from disk (unless it's a dynamic extension)."""
import importlib module = importlib.import_module('my_package.my_module') my_class = getattr(module, 'MyClass') my_instance = my_class()
def import_class(cl): d = cl.rfind(".") classname = cl[d+1:len(cl)] m = __import__(cl[0:d], globals(), locals(), [classname]) return getattr(m, classname)
如果您使用的是Django,则可以使用它。是的,我知道OP并没有要求使用django,但是我遇到了这个问题,寻找Django解决方案,没有找到一个解决方案,并将其放在这里供下一个寻找它的下一个男孩/女孩使用。
# It's available for v1.7+
# https://github.com/django/django/blob/stable/1.7.x/django/utils/module_loading.py
from django.utils.module_loading import import_string
Klass = import_string('path.to.module.Klass')
func = import_string('path.to.module.func')
var = import_string('path.to.module.var')
请记住,如果您要导入没有.
,re
或的东西,请argparse
使用:
re = __import__('re')