假設我有一個文件夾Awesome_stuff/my_module
,它包含以下文件:my_algorithm.py
,my_settings.py
,my_utils.py
。 主文件my_algorithm.py
包含以下行:使子模塊在同一Python模塊內彼此可見
# my_algorithm.py
import my_utils as mu
from my_settings import My_settings
def alg():
# do something
if __name__ == "__main__":
alg()
運行python my_algorithm.py
不會產生任何問題。然而,如果我想在我的Python庫中安裝這個模塊,事情就會改變。爲了做到這一點,我添加一個空__init__.py
文件my_module
文件夾中的my_module
文件夾內,外,我把一個setup.py
文件看起來像這樣:
from setuptools import setup
setup(
name = 'Awesome_stuff',
version = '1.0.0',
packages = ['my_module'],
# # dependencies
install_requires = ['numpy','scipy', 'numpydoc>=0.5', 'pyomo>=4.3.11388', 'mock>=1.1.3'],
# # project metadata
author = 'Me',
author_email = '[email protected]',
description = 'This module contains awesome stuff',
license = 'BSD',
url = 'http://my_website.com',
download_url = 'my_download_address.com'
)
運行python setup.py install
產生卵子和模塊安裝在我的Python圖書館。現在主要的文件夾Awesome_stuff
包含:
Awesome_stuff.egg-info
build (folder created during installation)
dist (folder created during installation)
my_module (my original folder plus __init__.py)
setup.py
爲了執行一些等同於原來的python my_algorithm.py
我現在可以創建包含有類似from my_module.my_algorithm import *
一個新的Python文件test.py
,然後執行alg()
。
不幸的是,線from my_module.my_algorithm import *
生成以下錯誤:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.macosx-10.11-intel/egg/my_module/my_algorithm.py", line 25, in <module>
ImportError: No module named my_utils
我怎樣才能解決這個問題,而無需修改原來的三個模塊的文件?我看不出這裏出了什麼問題。
此外,import my_module
不會產生任何錯誤。我在這裏有點困惑。 當模塊是獨立文件夾時,爲什麼從同一文件夾導入子模塊並在Python庫中安裝時無法工作?
更一般的問題:導入/使用可能相互依賴的子模塊的正確/建議的方式是什麼?文件__init__.py
可能在這種情況下起作用嗎?
感謝。
OS X埃爾隊長,Python的2.7.10
EDIT
作爲一個例子,我看着Python庫Zen,其以類似的方式構造:
Zen
build
zen
folder1
folder2
...
__init__.py
graph.pxd
graph.pyx
digraph.pxd
digraph.pyx
...
Makefile
setup.py
在這種情況下,digraph.pyx
(即覆蓋一些graph.pxd
聲明)包含行from graph cimport *
,這當然不會導致任何問題。請注意,它不會說:from zen.graph cimport *
。
最後的編輯
當使用cimport
你可以以設置*.pxd
文件的路徑定義package_data
內setup.py
。這就是爲什麼cimport
不需要上面例子中的絕對導入。但是,對於*.py
文件(據我所知),這是不可能的,唯一的方法是使用絕對和相對導入。
是的,這樣可以解決問題,但似乎並不正確。在正式創建模塊之前和之後,模塊和子模塊的名稱空間和層次結構應該是等效的。否則,只有因爲他決定創建一個模塊而需要返回並修改所有「import ...」。 – Gioker
@Gioker是的,好吧,他們不是。抱歉。在添加'__init__'之前,沒有適當的名稱空間。你還沒有創建一個模塊。你已經有了單獨的模塊。你將它們組合成一個包。 –
@Gioker絕對導入是推薦的方式: https://www.python.org/dev/peps/pep-0008/#imports –