以下是我假設的路徑
package
├── init.py
├── subpackage1
│ ├── init.py
│ ├── moduleX.py
│ └── moduleY.py
├── subpackage2
│ ├── init.py
│ └── moduleZ.py
└── moduleA.py
路徑參考
今天我在moduelX.py要import moduleZ.py裡的egg function
我出現了以下狀況:
我有嘗試用sys.path.append把目錄的路徑放進去,是可以解決問題的。
但我想知道如果不透過sys.path.append的方式,為甚麼會出現錯誤
一直找不到解決方式,請求大大解惑,謝謝。
參考的文章
Python Documentation:
Note that relative imports are based on the name of the current module. Since the name of the main module is always
"__main__"
, modules intended for use as the main module of a Python application must always use absolute imports.相對 import 的運作是以目前的模組名稱為依據。因為主模組的名稱永遠是
"__main__"
,所以如果一個模組預期被用作 Python 應用程式的主模組,那它必須永遠使用絕對 import。
以及 PEP 328:
Relative imports use a module’s
__name__
attribute to determine that module’s position in the package hierarchy. If the module’s name does not contain any package information (e.g. it is set to ‘__main__
’) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.相對 import 通過使用模組的
__name__
屬性來確定模組在包層次結構中的位置。如果該模組的名稱不包含任何包資訊(例如,它被設定為__main__
),那麼相對 import 會認為這個模組就是頂層模組,而不管模組在檔案系統上的實際位置。
意思是,當你直接運行 moduleX.py
的時候,moduleX.py
是程式的入口點 (Entry point),因此 __name__
== "__main__"
,moduleX.py
被認為是頂層 module,上面再沒有其他的 module。
建立 root_directory
及 root.py
,從 root.py
調用 moduleX.py
,令 root.py
成為頂層
root_directory
├── root.py
└── package
├── __init__.py
├── subpackage1
| ├── __init__.py
| └── moduleX.py
└── subpackage2
├── __init__.py
└── moduleZ.py
# root.py
from package.subpackage1 import moduleX
# moduleX.py
from ..subpackage2.moduleZ import egg
egg()
# moduleZ.py
def egg():
pass
package
├── subpackage1
| ├── __init__.py
| └── moduleX.py
└── subpackage2
├── __init__.py
└── moduleZ.py
# moduleX.py
from package.subpackage2.moduleZ import egg
egg()
# moduleZ.py
def egg():
pass
把 moduleX.py
當成 module 來執行:
$ python -m package.subpackage1.moduleX
各式各樣的添加路徑
繼續深入研究方向:__name__
、__package__
分析過程:
https://stackoverflow.com/questions/16981921/relative-imports-in-python-3
https://stackoverflow.com/questions/30669474/beyond-top-level-package-error-in-relative-import