除此之外,Pycharm 还为嵌套文件夹做了奇怪的工作。
假设我们有main.py,如下所示:
try:
import Module
print("Direct import")
except ImportError:
from os.path import abspath, dirname
from sys import path
path.append(dirname(abspath(__file__)) + "/..")
import Module
print("Relative import")
from os import getcwd
print(f"Current script dir: {__file__}")
print(f"Module dir: {Module.__file__}")
print(f"Working dir: {getcwd()}")
而Module.__init__ 什么都没有。
对于以下结构:
Project
├ Source
│ └ main.py
└ Module
└ __init__.py
执行main.py会直接导入。
Direct import
Current script dir: Z:/github/PersonalToolkit/Source/main.py
Module dir: Z:\github\PersonalToolkit\Module\__init__.py
Working dir: Z:\github\PersonalToolkit\Source
但是,对于以下结构:
Project
└ Root
├ Source
│ └ main.py
└ Module
└ __init__.py
Relative import
Current script dir: Z:/github/PersonalToolkit/Root/Source/main.py
Module dir: Z:\github\PersonalToolkit\Root\Source/..\Module\__init__.py
Working dir: Z:\github\PersonalToolkit\Root\Source
然而对于这两种情况,Pycharm 显示相同的导入提示。
由此我们可以猜测 Pycharm 在运行时会将 Project Root 添加到 sys.path 并创建这种不同的行为。
但是,我们不能指望在通常的运行案例(主要是控制台)上的行为会得到一致的结果。
相反,在外部文件夹中导入模块时,只需像这样导入:
from os.path import abspath, dirname
from sys import path
path.append(dirname(abspath(__file__)) + "/..")
import Module
这确实违反了PEP-8,而且看起来并不干净。最好有 __main__.py 在外面,让它导入 main.py 并让 main.py 在导入时运行代码 - 没有 if __name__ == "__main__": 样板。
Project
├ __main__.py
├ Source
│ └ main.py
└ Module
└ __init__.py