我的Python开发工作流程
这是开发Python软件包的基本过程,其中包含了我认为是社区中的最佳实践。这是基本的-
如果您真的很认真地开发Python软件包,那么它还有更多的东西,每个人都有自己的喜好,但是它应该作为入门的模板,然后进一步了解其中涉及的部分。基本步骤是:
- 使用
virtualenv
隔离 setuptools
用于创建可安装的软件包并管理依赖项python setup.py develop
以开发模式安装该软件包
虚拟环境
首先,我建议使用
virtualenv以获得一个隔离的环境来开发您的程序包。在开发过程中,您将需要安装,升级,降级和卸载程序包的依赖项,而您不需要
- 您的开发依赖关系会污染整个系统
site-packages
- 在整个系统范围
site-packages
内影响您的开发环境 - 版本冲突
在整个系统范围内污染
site-packages是不好的,因为即使您的小型项目只需要该依赖项,安装的任何软件包都将对使用该系统Python的所有Python应用程序可用。而且它只是安装在一个新版本中,该版本将覆盖系统范围内的新版本
site-packages,并且与依赖它的$ {important_app}不兼容。你明白了。
在整个系统范围内
site-packages影响开发环境是很糟糕的,因为您的项目可能取决于系统Python已有的模块
site-packages。因此,您忘记正确地声明您的项目依赖于该模块,但是一切正常,因为它始终在本地开发框中。在发布软件包之前,人们会尝试安装它或将其投入生产等。在干净的环境中进行开发会迫使您正确声明依赖项。
因此, virtualenv 是具有自己的Python解释器和模块搜索路径的隔离环境。它基于您先前安装但与之隔离的Python安装。
要创建的virtualenv,安装
virtualenv通过广泛使用Python它安装到你的系统包
easy_install或
pip:
sudo pip install virtualenv
请注意,这将是您 唯一 一次以root用户身份(使用sudo)在全局站点程序包中安装某些程序。之后的一切都会在您要创建的virtualenv内部发生。
现在创建一个virtualenv来开发您的软件包:
cd ~/pyprojectsvirtualenv --no-site-packages foobar-env
这将创建一个目录树
~/pyprojects/foobar-env,即您的virtualenv。
要激活的virtualenv,
cd到里面
source了
bin/activate script:
~/pyprojects $ cd foobar-env/~/pyprojects/foobar-env $ . bin/activate(foobar-env) ~/pyprojects/foobar-env $
注意前导点
.,这是
sourceshell命令的简写。还要注意提示如何更改:
(foobar-env)意味着您处于激活的virtualenv内部(始终需要隔离才能起作用)。因此,每次您打开新的终端标签或SSH会话等时,请激活您的环境。
如果您现在
python在该激活的环境中运行,它将实际
~/pyprojects/foobar-env/bin/python用作解释器,并具有其自己的
site-packages隔离模块搜索路径。
setuptools软件包
现在创建您的包。基本上,您将希望带有的
setuptools软件包
setup.py正确声明您的软件包的元数据和依赖项。您可以按照setuptools文档的要求自行完成此操作,也可以使用Paster模板创建软件包框架。要使用Paster模板,请安装
Pastescript到您的virtualenv中:
pip install Pastescript
让我们为新程序包创建一个源目录,以使事情井井有条(也许您想将您的项目分成几个程序包,或者稍后使用源程序中的依赖项):
mkdir srccd src/
现在创建您的包,执行
paster create -t basic_package foobar
并在交互式界面中回答所有问题。大多数是可选的,只需按ENTER即可保留默认值。
这将创建一个名为的包(或更准确地说,是setuptools发行版)
foobar。这是那个名字
- 人们将使用
easy_install
或安装您的软件包pip install foobar
- 其他软件包将使用的名称取决于您的
setup.py
- 在PyPi上将被称为什么
在内部,几乎总是创建一个称为的Python包(如带有的目录
__init__.py)。这不是必需的,顶级Python包的名称可以是任何有效的包名称,但这是一个通用的约定与发行版相同这就是为什么将两者分开很重要但并不总是那么容易的原因,因为顶级python软件包名称是什么
- 人(你)将使用通过导入你的包
import foobar
或from foobar import baz
因此,如果您使用粘贴模板,它将已经为您创建了该目录:
cd foobar/foobar/
现在创建您的代码:
vim models.py
models.py
class Page(object): """A dumb object wrapping a webpage. """ def __init__(self, content, url): self.content = content self.original_url = url def __repr__(self): return "<Page retrieved from '%s' (%s bytes)>" % (self.original_url, len(self.content))
并
client.py在使用的同一目录中
models.py:
client.py
import requestsfrom foobar.models import Pageurl = 'http://www.stackoverflow.com'response = requests.get(url)page = Page(response.content, url)print page
在中声明对
requests模块的依赖
setup.py:
install_requires=[ # -*- Extra requirements: -*- 'setuptools', 'requests', ],
版本控制
src/foobar/现在是您要置于版本控制下的目录:
cd src/foobar/git initvim .gitignore
.gitignore
*.egg-info*.py[co]git add .git commit -m 'Create initial package structure.
将软件包作为开发工具安装
现在是时候以开发模式安装软件包了:
python setup.py develop
这会将
requests依赖关系和 您的
软件包安装为开发工具。因此,它已链接到您的virtualenv的站点程序包中,但仍然
src/foobar可以在您进行更改的地方使用,并使它们立即在virtualenv中处于活动状态,而无需重新安装程序包。
现在,对于您的原始问题,使用相对路径导入:我的建议是,不要这样做。现在您已经有了一个正确的setuptools程序包,该程序包已安装并且可以导入,您当前的工作目录不再重要。照做
fromfoobar.models importPage或类似,声明该对象所在的位置的完全限定名称。对于您自己和其他阅读您代码的人来说,这使您的源代码更具可读性和可发现性。
现在,您可以通过在
python client.py激活的virtualenv内部的任何位置执行代码来运行代码。
pythonsrc/foobar/foobar/client.py工作正常,您的软件包已正确安装,工作目录不再重要。
如果您想更进一步,甚至可以为CLI脚本创建setuptools入口点。这将
bin/something在您的virtualenv中创建一个脚本,您可以从shell中运行它。
setuptools console_scripts入口点
setup.py
entry_points=''' # -*- Entry points: -*- [console_scripts] run-fooobar = foobar.main:run_foobar ''',
client.py
def run_client(): # ...
main.py
from foobar.client import run_clientdef run_foobar(): run_client()
重新安装软件包以激活入口点:
python setup.py develop
然后你去
bin/run-foo。
一旦您(或其他人)在virtualenv外部真正安装了软件包,入口点将在
/usr/local/bin/run-foo或类似的地方,或自动在的地方
$PATH。



