我正在处理一个Django项目,该项目包含一个应用程序。应用程序将在GPL下发布,所以我想将它与项目分开开发--一个使用该应用程序的个人站点。我试图在项目和应用程序中使用基于我的域名的包结构,这就是我遇到问题的地方。
下面是我的文件结构(在适当的情况下带有__init__.py文件):
$HOME/django-sites/mydomain
$HOME/django-apps/mydomain/cms而我的平易近:
$HOME/django-sites:$HOME/django-apps如果我启动Python解释器(从文件系统上的任何目录),我可以从站点导入类,但不能导入应用程序。如果我颠倒了PYTHONPATH (应用程序第一,然后是站点)中两个条目的顺序,我可以从应用程序中导入,但不能导入站点。
看起来Python只是试图从包含包名第一部分的PYTHONPATH中的第一个条目导入。对吗?这是预期的行为吗?如果是这样的话,我只能将模块粘贴在包结构中,比如域/app1、域/app2,如果它们生活在相同的目录结构中--不管PYTHONPATH是什么。
这不是停止显示,因为我可以重命名网站,但它与我预期的大不相同。Python教程提到了__path__,但我不知道如何使用它:
包支持另一个特殊属性__path__。它被初始化为一个列表,其中包含在执行该文件中的代码之前保存包的__init__.py的目录的名称。可以修改此变量;这样做会影响将来对包中包含的模块和子包的搜索。
虽然这个特性通常不需要,但它可以用于扩展包中的一组模块。
还有其他人遇到过这个吗?我能用__path__做些什么来使这个函数像预期的那样吗?
发布于 2009-08-06 01:18:44
你的分析似乎是对的。python路径用于定位要导入的模块;python导入它发现的第一个模块。我不知道你能做些什么来解决这个问题,只是给模块命名不同的东西,或者把它们放在搜索路径中的同一个位置。
发布于 2009-08-06 02:31:53
下面是如何在包的__path__中使用__init__.py:
$ export PYTHONPATH=$HOME/django-sites
$ ls -d $HOME/django*
django-apps/ django-sites/
$ cat /tmp/django-sites/mydomain/__init__.py
import os
_components = __path__[0].split(os.path.sep)
if _components[-2] == 'django-sites':
_components[-2] = 'django-apps'
__path__.append(os.path.sep.join(_components))
$ python -c'import mydomain; import mydomain.foo'
foo here /tmp/django-apps/mydomain/foo.pyc
$ 正如您所看到的,这使得django-apps/mydomain包的内容成为mydomain包(其__init__.py驻留在django-sites/mydomain下)的一部分--如果使用这种方法,您也不需要sys.path上的django-apps。
这是否比one @defrex的答案更好可能还没有定论,但由于包丰富其__path__是python程序员包中非常重要的一点,我想我最好还是说明一下;-)。
发布于 2009-08-06 01:45:47
基本上,您有两个模块,名为相同的东西(我的域)。为什么不像这样设置你的PYTHONPATH呢?
$HOME/django-sites:$HOME/django-apps/mydomain这样可以避免你的进口问题。
https://stackoverflow.com/questions/1236443
复制相似问题