这是目前个人一个尝试。随着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>
。这也是我建议你两个都安装的缘由,这两个工具互补仍是不错的。