2009-08-06 46 views
2

我正在研究包含单个应用程序的Django项目。该应用程序将在GPL下发布,因此我希望将其与该项目分开开发 - 使用该应用程序的个人网站。我试图在项目和应用程序中使用基于我的域名的包结构,这就是我遇到问题的地方。在共享一部分包结构的不同目录中创建多个Python模块

这是我的文件结构(与__init__.py文件在适当情况下):

$HOME/django-sites/mydomain 
$HOME/django-apps/mydomain/cms 

我的PYTHONPATH:

$HOME/django-sites:$HOME/django-apps 

如果我火了Python解释器(从文件系统上的任何目录)我可以从网站导入类,但不能导入应用程序。如果我颠倒PYTHONPATH中的两个条目(应用程序第一,然后站点)的顺序,我可以从应用程序导入,但不能从站点导入。

它看起来像Python只尝试从PYTHONPATH中的第一个条目导入,该条目包含软件包名称的第一部分。那是对的吗?这是预期的行为?如果是这样,我只能将模块粘贴到像domain/app1,domain/app2这样的包结构中(如果它们处于相同的目录结构中) - 不管PYTHONPATH。

这不是显示限制器,因为我可以重命名该站点,但它与我所期望的大不相同。 Python教程提到__path__,但我不知道如何使用它:

包支持一个更多的特殊属性__path__。在执行该文件中的代码之前,它被初始化为一个包含包含__init__.py的目录名称的列表。这个变量可以修改;这样做会影响将来对包中包含的模块和子包的搜索。

虽然此功能通常不是必需的,但它可用于扩展包中找到的一组模块。

有没有人遇到过这个?有没有什么我可以用__path__来完成这个功能?

回答

1

你的分析似乎是正确的。 python路径用于查找要导入的模块; python导入它找到的第一个。我不确定你能做些什么来解决这个问题,而不是将你的模块命名为不同的东西,或者把它们放在搜索路径的相同位置。

1

你基本上有两个模块命名为相同的东西(mydomain)。为什么不像这样设置你的PYTHONPATH?

$HOME/django-sites:$HOME/django-apps/mydomain 

它会避免您的导入问题。

+1

无论如何,这是正确的 - 第三方应用程序应该位于python导入命名空间的顶部(即'from cms import models')。 所有项目特定的应用程序应该位于您的项目模型中(例如'from [project] .apps。[appname] import models') – SmileyChris 2009-08-06 01:54:46

+0

因此,如果我要开发多个可再分发的第三方应用程序,独特的封装结构? – 2009-08-06 12:11:03

4

这里有一个封装的__init__.py如何__path__中拟用于:

$ 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 
$ 

如你所见,这使得mydomaindjango-apps/mydomain一部分(其__init__.py所在django-sites/mydomain下)的内容 - 你不如果您使用这种方法,则不需要django-appssys.path

这是否是一个比@ defrex的答案更好的安排可能没有实际意义,但是因为一个包的丰富其__path__是python程序员工具包的一个非常重要的部分,所以我认为我最好说明它; - )。

+0

谢谢,我希望Python教程有这样一个例子。现在有道理。 :) – 2010-03-18 15:40:59

相关问题