python_import

how to correctly import a python module…

package/module

module就是一个python的源文件
package就是带有__init__.py的目录, package可以使用.来索引目录下的module或者package

1
2
3
dir1
dir2
__init__.py

则可以使用dir1.dir2访问dir2

相对导入/绝对导入

python3中使用的默认导入为绝对导入

1
2
import xxx
from xxx import xxx

相对导入

1
from .xxx import xxx

注意相对导入是使用当前文件的name属性作为起点。所以如果当前文件是入口文件即 name == “main“那么相对导入是会失败的。使用python -m xxx.py是可以成功的

python绝对导入寻找module的顺序

  1. sys.modules缓存
    缓存中包含
  • builtins, os等python默认加载的module
  • 用户import的
    • 所以如果本地的module与python默认加载的module重名是找不到的
1
2
3
4
5
6
>>> import sys
>>> sys.modules.keys()
dict_keys(['builtins', 'sys', '_frozen_importlib', '_imp', '_warnings', '_thread', '_weakref', '_frozen_importlib_external', '_io', 'marshal', 'nt', 'winreg', 'zipimport', 'encodings', 'codecs', '_codecs', 'encodings.aliases', 'encodings.utf_8', '_signal', '__main__', 'encodings.latin_1', 'io', 'abc', '_weakrefset', 'site', 'os', 'errno', 'stat', '_stat', 'ntpath', 'genericpath', 'os.path', '_collections_abc', '_sitebuiltins', 'sysconfig',
'_bootlocale', '_locale', 'encodings.gbk', '_codecs_cn', '_multibytecodec', 'types', 'functools', '_functools', 'collections', 'operator', '_operator', 'keyword', 'heapq', '_heapq', 'itertools', 'reprlib', '_collections',
'weakref', 'collections.abc', 'importlib', 'importlib._bootstrap', 'importlib._bootstrap_external', 'warnings', 'importlib.util', 'importlib.abc', 'importlib.machinery', 'contextlib', 'mpl_toolkits', 'atexit'])
>>>
  1. sys.path中寻找
    sys.path默认添加入口文件所在目录
    1
    2
    import sys
    print(sys.path)
1
2
3
4
dir1
dir2
dir3
main.py

所以在main.py中假如有

1
import dir1

然后使用python dir3/main.py是会报错的,因为sys中只会添加dir3目录,而在dir3目录下是找不到dir1的

解决方案:

1 手动修改sys,添加dir1目录
2 python -m dir3.main