我正在使用python 3.7。使用时imp
,我注意到相对导入的工作方式不同,具体取决于相对导入发生的位置。
例如,我有以下目录:
.
├── __init__.py
└── dir2
├── __init__.py
├── a.py
└── b.py
和文件内容如下:
~/personal/dir1 via v3.7.7 via C py372
❯ cat dir2/__init__.py
from .a import default
print("default is", default)
~/personal/dir1 via v3.7.7 via C py372
❯ cat dir2/a.py
default = 12
~/personal/dir1 via v3.7.7 via C py372
❯ cat dir2/b.py
from .a import default
print("default is", default)
~/personal/dir1 via v3.7.7 via C py372
我imp.load_source
同时使用dir2/__init__.py
and dir2/b.py
,得到以下结果:
❯ ipython
Python 3.7.7 (default, May 6 2020, 04:59:01)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import imp
/Users/user/anaconda3/envs/py372/bin/ipython:1: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
#!/Users/user/anaconda3/envs/py372/bin/python
In [2]: imp.load_source("m", "dir2/__init__.py")
default is 12
Out[2]: <module 'm' from 'dir2/__init__.py'>
In [3]: imp.load_source("m", "dir2/b.py")
---------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-3-40c4f63c0bb1> in <module>
----> 1 imp.load_source("m", "dir2/b.py")
~/anaconda3/envs/py372/lib/python3.7/imp.py in load_source(name, pathname, file)
167 spec = util.spec_from_file_location(name, pathname, loader=loader)
168 if name in sys.modules:
--> 169 module = _exec(spec, sys.modules[name])
170 else:
171 module = _load(spec)
~/anaconda3/envs/py372/lib/python3.7/importlib/_bootstrap.py in _exec(spec, module)
~/anaconda3/envs/py372/lib/python3.7/importlib/_bootstrap_external.py in exec_module(self, module)
~/anaconda3/envs/py372/lib/python3.7/importlib/_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)
~/personal/dir1/dir2/b.py in <module>
----> 1 from .a import default
2 print("default is", default)
ImportError: attempted relative import with no known parent package
为什么与其他 python 文件imp.load_source
的行为不同?__init__.py