Python如何处理同名模块和包?
假设我有一个模块叫做 foo.py
,还有一个包叫做 foo/
。如果我调用了某个东西,
import foo
那么这两者中哪个会被加载呢?我该怎么指定我想加载模块还是包呢?
3 个回答
15
也许你想把你的类从 foo.py
文件移动到 __init__.py
文件里。
这样的话,你就可以从这个包里导入它们,同时也可以导入一些可选的子包:
文件 foo/__init__.py
:
class Bar(object):
...
文件 foo/subfoo.py
:
class SubBar(object):
...
文件 mymodule.py
:
from foo import Bar
from foo.subfoo import SubBar
20
其实,这是可以做到的,只要手动引导导入机制使用一个 .py
文件,而不是目录。(这段代码测试得不太充分,但看起来是有效的)。2020年更新:请注意,这需要使用自定义的 import_module()
函数,而不是普通的 import
语句。不过,随着现代 Python3 及其 importlib
模块的出现,可能也能让普通的 import
语句以相同的方式工作。(请注意,这个回答展示了 Python 的灵活性。这不是鼓励你在应用中使用这种方法。只有在你知道自己在做什么的情况下才使用它。)
文件 foo.py
print "foo module loaded"
文件 foo/__init__.py
print "foo package loaded"
文件 test1.py
import foo
文件 test2.py
import os, imp
def import_module(dir, name):
""" load a module (not a package) with a given name
from the specified directory
"""
for description in imp.get_suffixes():
(suffix, mode, type) = description
if not suffix.startswith('.py'): continue
abs_path = os.path.join(dir, name + suffix)
if not os.path.exists(abs_path): continue
fh = open(abs_path)
return imp.load_module(name, fh, abs_path, (description))
import_module('.', 'foo')
运行
$ python test1.py
foo package loaded
$ python test2.py
foo module loaded
33
我认为这个包总是会被加载。根据我所知道的,你无法避免这个情况。所以要么改一下包的名字,要么改一下模块的名字。相关文档可以查看这里:http://docs.python.org/tutorial/modules.html#the-module-search-path