我正在用python2.7开发自己的模块。它位于~/Development/.../myModule
,而不是/usr/lib/python2.7/dist-packages
或{
/project-root-dir
/server
__init__.py
service.py
http.py
/client
__init__.py
client.py
client/client.py
包括PyCachedClient
类。我遇到了导入问题:
我没有将PythonPath设置为包括我的project-root-dir
,因此何时服务器.http试图包括客户端.PyCachedClient,它尝试从相对路径加载,但失败。我的问题是-我应该如何以一种好的、Python式的方式设置所有的路径/设置?我知道每次打开控制台并尝试运行服务器时,我都可以在shell中运行export PYTHONPATH=...
,但我想这不是最好的方法。如果我的模块是通过PyPi(或类似的东西)安装的,我会把它安装在/usr/lib/python...
路径中,然后自动加载。在
我将非常感谢关于python模块开发的最佳实践的提示。在
我的Python开发工作流
这是开发Python包的一个基本过程,它包含了我认为是社区中最佳实践的东西。这是基本的-如果你真的很认真地开发Python包,还有更多的东西要做,每个人都有自己的偏好,但它应该作为一个模板,开始学习,然后了解更多相关的部分。基本步骤包括:
python setup.py develop
以开发模式安装该包虚拟人
首先,我建议使用^{} 来获得一个独立的环境来开发您的包。在开发过程中,您将需要安装、升级、降级和卸载包的依赖项,而您并不希望
site-packages
来影响您的开发环境污染系统范围内的
site-packages
是很糟糕的,因为您在那里安装的任何包都可以用于您安装的使用系统Python的Python应用程序,即使您只是需要为您的小项目提供这种依赖性。它只是安装在一个新版本中,它重写了系统范围内的site-packages
,并且与依赖它的${important_app}不兼容。你明白了。在让您的系统范围的
site-packages
影响您的开发环境是不好的,因为您的项目可能依赖于系统Python的site-packages
中已有的模块。因此,您忘记正确声明您的项目依赖于该模块,但一切都正常,因为它总是存在于您的本地开发框中。直到你发布你的软件包,人们试图安装它,或者把它推到生产环境中,等等。。。在干净的环境中开发会迫使您正确地声明依赖项。在因此,virtualenv是一个独立的环境,具有自己的Python解释器和模块搜索路径。它基于您以前安装的Python安装,但与之隔离。在
要创建virtualenv,请使用
easy_install
或pip
将其安装到系统范围的Python中,以安装virtualenv
包:请注意,这将是唯一的时间,您将以root用户身份(使用sudo)安装到全局站点包中。在这之后的一切都将发生在你即将创建的virtualenv中。在
现在创建一个virtualenv来开发您的软件包:
^{pr2}$这将创建一个目录树
~/pyprojects/foobar-env
,这是您的虚拟环境。在要激活virtualenv,
cd
进入其中,source
并bin/activate script
:注意前导点
.
,它是source
shell命令的简写。还要注意提示是如何变化的:(foobar-env)
表示您在激活的virtualenv中(并且总是需要隔离才能工作)。所以每次打开新的终端选项卡或SSH会话时都要激活env。。在如果您现在在激活的env中运行
python
,那么它实际上将使用~/pyprojects/foobar-env/bin/python
作为解释器,有自己的site-packages
和独立的模块搜索路径。在setuptools包
现在来创建你的包。基本上,您需要一个带有
setup.py
的setuptools
包来正确声明包的元数据和依赖关系。您可以通过跟随setuptools documentation自行完成此操作,或者使用Paster templates创建一个包框架。要使用粘贴模板,请将PasteScript
安装到您的virtualenv中:让我们为我们的新包创建一个源目录,使事情井井有条(也许你会想把你的项目分成几个包,或者稍后使用源代码的依赖项):
现在要创建包,请执行以下操作:
并在交互界面中回答所有问题。大多数是可选的,只需按ENTER键就可以保留默认值。在
这将创建一个名为
foobar
的包(或者更准确地说,setuptools发行版)。这个名字easy_install
或pip install foobar
安装您的包setup.py
中其他包将用来依赖您的包的名称在内部,您几乎总是创建一个调用相同的Python包(如“带有
__init__.py
的目录”中)。这不是必需的,顶级Python包的名称可以是任何有效的包名,但通常的惯例是将其命名为与发行版相同的名称。这就是为什么要把两者分开很重要,但并不总是那么容易。因为顶层的python包名是什么import foobar
或from foobar import baz
导入您的包因此,如果您使用粘贴模板,它将已经为您创建了该目录:
现在创建代码:
models.py
以及
client.py
在使用models.py
的同一目录中:client.py
声明对^{中
requests
模块的依赖关系:版本控制
src/foobar/
是您现在要置于版本控制之下的目录:.gitignore
将您的软件包安装为开发鸡蛋
现在是在开发模式下安装软件包的时候了:
这将把
requests
依赖项和您的包作为一个开发鸡蛋安装。所以它被链接到你的virtualenv站点包中,但是仍然存在于src/foobar
中,你可以在那里进行更改并让它们立即在virtualenv中活动,而无需重新安装您的软件包。在对于你最初的问题,使用相对路径导入:我的建议是,不要这样做。现在您已经有了一个正确的setuptools包,它已经安装并可导入,那么您当前的工作目录就不再重要了。只需执行
from foobar.models import Page
或类似操作,声明对象所在的完全限定名。这使得您的源代码更加可读和可发现,对于您自己和其他阅读您的代码的人来说。在现在,您可以通过在激活的virtualenv中的任何地方执行
python client.py
来运行代码。python src/foobar/foobar/client.py
工作正常,包安装正确,工作目录不再重要。在如果您想更进一步,甚至可以为CLI脚本创建setuptools入口点。这将在virtualenv中创建一个可以从shell运行的
bin/something
脚本。在setuptools控制台脚本入口点
setup.py
client.py
main.py
重新安装软件包以激活入口点:
就这样,
bin/run-foo
。在一旦您(或其他人)在virtualenv之外真正安装了您的包,入口点将位于
/usr/local/bin/run-foo
或类似的地方,它将自动位于$PATH
。在进一步的步骤
建议阅读:
因此,您有两个包,第一个包的模块名为:
第二个模块名为:
^{pr2}$如果您想假设这两个包都在导入路径(
sys.path
)中,并且您想要的类在client/client.py
中,那么在您的服务器中,您必须执行以下操作:您请求的符号来自
client
,而不是client.client
,根据您的描述,这不是该符号的定义位置。在我个人会考虑让这个包(也就是说,在文件夹中放一个}作为该包的子包。然后(a)如果你想(
__init__.py
,并给它一个合适的python包名),并将client
和{from ...client.client import something
),你可以做相对导入,(b)你的项目更适合重新发布,而不是把两个非常通用的包名放在python模块层次结构的顶层。在相关问题 更多 >
编程相关推荐