這是目前個人一個嘗試。隨着uliweb的項目多起來(爲了便於管理和隔離,咱們會考慮將不一樣的功能拆分爲不一樣的項目),須要有時複用其它項目的模塊,好比:用戶管理等。uliweb項目是能夠將一個知足條件的python包(使用 uliweb makeapp appname
)做爲外部的app在INSTALLED_APPS中配置的。可是對於使用 uliweb makeproject projectname
生成的項目,卻缺省不是一個能夠處理的python包,所以直接是沒法在另外一個項目中導入的,爲了實現這一點,我對uliweb進行了優化。python
爲了讓一個目錄是能夠導入的,咱們通常會使用setup.py來編寫一個安裝腳本,在其中寫上對應要安裝的包和目錄。一個uliweb的project是什麼結構呢?linux
project/ apps/ settings.ini app1/ app2/ wsgi_handler.py
咱們全部的app都是放在apps目錄下,因此它是一個重要的目錄。好比咱們的項目目錄是project,所以對於app1這個app來講,我但願能夠在安裝後使用 import project.app1
來導入。那麼咱們會發現,但願導入的包名和實際的目錄是不對應的。那麼如何處理呢?git
在寫setup.py時,有兩個變量很重要:packages和package_dir,它一個是用來表示安裝後將出現的包名,能夠是多個,另外一個是一個配置,用來表示安裝包與實際目錄的關係。所以,咱們能夠這樣寫:github
setup(packages=['project'], package_dir={'project':'apps'})
這樣就告訴安裝程序,在安裝時建立包爲project,可是它實際的文件是來自當前目錄的apps下的內容。web
考慮好這一點,我就開始改造uliweb。windows
首先是考慮在執行makeproject時自動拷貝一個setup.py文件到新建的項目目錄下。它的內容是:app
import uliweb from uliweb.utils.setup import setup import apps __doc__ = """doc""" setup(name='{{=project_name}}', version=apps.__version__, description="Description of your project", package_dir = {'{{=project_name}}':'apps'}, packages = ['{{=project_name}}'], include_package_data=True, zip_safe=False, )
能夠看到,它裏面有一個變量 {{=project_name}}
,表示這個值將用實際的項目路徑名進行替換。所以,若是咱們執行 uliweb makeproject project
會在當前目錄下生成 project 目錄,在其中會有一個setup.py文件,makeproject命令會自動將模板中的 {{=project_name}}
替換爲 project
。函數
而後咱們還須要在apps下添加一個 __init__.py
,它定義了 __version__
變量值,這個值會用在 setup.py中。用來表示項目的版本。工具
使用setup.py來安裝模塊時主要有兩種方式:install和develop。注意develop是setuptools中特有的。所以須要在你的環境中安裝setuptools,同時還建議把pip也安裝。最好的方式是使用virtualenv,它會自動安裝這兩個包。優化
對於install,它會把對應的文件所有拷貝到python的site-packages下,對於develop,它只會在site-packages下的easy_install.pth中加一個路徑,不會真正拷貝。
對於install,由於會拷貝文件,因此不會有太大的問題。只不過若是你的項目常常更新,須要不停地執行install來更新。
所以,不少時候我會使用develop來安裝。可是在實際處理過程當中發現develop是存在問題的。主要問題就是不會進行實際文件的拷貝。由於咱們的包結構和實際的目錄結構不一樣,而拷貝的方式會建立這種結構,可是develop方式沒法實現這種包結構。因此有問題。
那麼怎麼解決呢?我在網上搜了半天,終於找到一種辦法,那就是建立: 符號鏈接 。符號鏈接是在linux下經常使用的一種方法。其實這種方法在windows下也是能夠用的。有這麼幾個方法可使用:
可是,在windows平臺下,這些方法除了unlink之外,都存在問題。看到網上說在python 3.2以後就能夠了。可是我運行的環境主要是python 2.6和2.7。因此須要不升級就能解決的方法。
找來找去,有兩個參考:
那麼個人實現是寫在 uliweb/utils/setup.py
中的,對原來的setuptools中的develop命令的幾個方法進行了特殊處理,如:
install_for_development 我在它以後添加了根據setup中的packages和package_dir來建立符號鏈接的處理。它支持包和子包。所以你可使用象
setup(packages=['project', 'project.batch'], package_dir={'project':'apps', 'project.batch':'batch'})
這樣的方式,將不一樣的目錄處理到一個包結構之下。
所以,若是你要使用uliweb的develop方式,而且在windows下,你須要安裝 ntfslink 這個包。爲何呢?
由於我發現,直接執行unlink去刪除一個symlink會報 [Error 5]
的錯誤。而 ntfslink.symlink 中的unlink方法能夠正確刪除。可是我又發現,ntfslink.symlink 中的create好象沒法建立正確的symlink,因此我仍是使用了stackoverflow中的建立symlink的方法。
其實前面已經寫了:
uliweb makeproject <projectname>
會在生成的 projectname 目錄下建立一個setup.py文件。你能夠打開修改它的內容以知足你的須要python setup.py install
或 python setup.py develop
來安裝你的項目,這樣就能夠在其它的項目中使用了。使用方式是 import project.app
,若是想反安裝,若是是使用develop安裝的話,能夠這樣 python setup.py develop -u
。可是使用install的話,報歉,沒戲了。因此這時可使用pip來作這事: pip uninstall <projectname>
。這也是我建議你兩個都安裝的緣由,這兩個工具互補仍是不錯的。