Python相对__import__

时间:2015-05-05 06:59:18

标签: python import

假设我有一个包含以下文件的模块包。空文件C:\codes\package\__init__.py和一些非平凡的文件:

一个位于C:\codes\package\first.py

def f():
    print 'a'

另一个位于C:\codes\package\second.py

def f():
    print 'b'

还有第三个文件:C:\codes\package\general.py,代码为

def myPrint(module_name):
    module = __import__(module_name)
    module.f()

if __name__ == '__main__':
    myPrint('first')
    myPrint('second')

当我运行后一个文件时,一切都很顺利。但是,如果我尝试执行包含

的文件C:\codes\test.py
if __name__ == '__main__':
    from package import general
    general.myPrint('first')
    general.myPrint('second')

我收到导入错误ImportError: No module named first。如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

首先,我怀疑你忘了你有一个(可能是空的)文件package\__init__.py,它使package成为一个包。否则,from package import general将无效。

第二种情况与第一种情况不同,因为你在一个包中。在包内,您不会import first,而是import .first。后者的等价描述为here,您可以在其中添加level=1作为参数,或者(但我不确定)将.first放入字符串并设置level } -1(如果它不是默认值,那么从文档中就不清楚了。)

此外,您必须至少提供globals(),因此正确的行是

module = __import__(module_name, globals(), level=1)

我找到了这个解决方案here

答案 1 :(得分:0)

在您的情况下,您应该从module_name导入package。使用fromlist参数:

getattr(__import__("package", fromlist=[module_name]), module_name)

答案 2 :(得分:0)

假设您正在使用Python 3,那只是因为此版本放弃了对implicit relative imports的支持。使用Python 2,它可以正常工作。

因此,您需要在C:\codes\package\general.py中使用相对导入,这会导致错误调用,或者将您的包添加到路径中。有点脏,但工作黑客将是:

def myPrint(module_name):
    pkg = os.path.dirname(__file__)
    sys.path.insert(0, pkg)
    try:
        module = __import__(module_name)
    except:
        raise
    finally:
        sys.path.remove(pkg)
    module.f()

也许您可以使用importlib模块实现更清晰的实施。