用循环导入包装python

时间:2012-01-12 20:16:56

标签: python import namespaces

我仔细研究了之前的问题,但我的情况略有不同......

我有一个目录,其中包含几个python类,可以在必要时在此处相互导入。我想开始将它们打包成更小的模块,主要用于组织目的。该软件包的核心组件设置了一个wsgi应用程序,然后其他模块为它提供了功能(到目前为止,这已经很有效,因为我可以在将其输入连接到Web应用程序之前在命令行上单独测试mod。)

我理解提供__init__.py模块的工作原理,命名空间以及释放控制权的方式。我遇到的麻烦是,某些情况下的模块互相导入。

例如,我有一个JSONEncoder用作许多cls调用的json.dumps()参数。该类几乎用于每个文件。如果我将这些模块中的一些移动到包中的子目录中,我将如何“向上一级”导入json编码器?我是否需要将父目录放在每个文件的PYTHONPATH中?使用单独的__init__.py文件为编码器提供自己的目录会更好吗?

或者,我是否最好放入一个向下钻取当前工作目录下方所有目录的函数并将它们添加到路径中?

目前包含所有代码的主目录本身并不是包...考虑到它们具有循环导入,将类迁移到子目录的最佳方法是什么?

修改

澄清:

我一直在开发的主要工作目录只是一个包含大约十个.py文件的常规目录,所有这些文件都包含名称类似文件名的类。目前整个事情只是.py文件的git repo。

-project
  search.py
  jsonencoder.py
  webapp.py
  modela.py
  modelb.py
  modelc.py

名称当然是出于示例目的。

现在我理解它(这可能是完全错误的),明智的做法是将这些模型打包在一起,正确吗?

-project
  search.py
  jsonencoder.py
  webapp.py
  -models
    __init__.py
    modela.py
    modelb.py
    modelc.py

但是反过来,project文件夹是否也需要__init__? modela如何使用jsonencoder导入它?

2 个答案:

答案 0 :(得分:1)

答案很简单:

只需使用您需要的子模块的完全限定名称

例如,在

mybundle/test/__init__.py 

你可以拥有这条线

import mybundle.JSONEncoder
  • 它会做正确的事。

例如,给定此模块结构:

├── mybundle
│   ├── __init__.py
│   ├── jsonencoder
│   │   ├── __init__.py
│   └── test
│       ├── __init__.py

文件定义如下:

[gwidion@powerpuff tmp]$ cat mybundle/__init__.py
import test

[gwidion@powerpuff tmp]$ cat mybundle/test/__init__.py
import mybundle.jsonencoder

[gwidion@powerpuff tmp]$ cat mybundle/jsonencoder/__init__.py
print 5

这有效:

[gwidion@powerpuff tmp]$ python
Python 2.7.1 (r271:86832, Apr 12 2011, 16:15:16) 
[GCC 4.6.0 20110331 (Red Hat 4.6.0-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mybundle
5
>>> 

答案 1 :(得分:0)

您可以尝试这样的事情(root是您的工作目录):

/root
  - file_a.py
  - file_b.py
  /JSONEncoder 
    - __init__.py
    - JSONEncoder.py

__init__.py为空,或者有pass或评论或其他内容。 然后,您可以(来自file_a.pyroot中的任何内容):

from JSONEncoder import JSONEncoder

并且可以访问JSONEncoder中的file_a.py。只要所有正在运行的代码都位于PYTHONPATH中,您就无需触摸/root,只需要在子目录中__init__.py。这种类型的目录布局非常有用,因为您可以隐藏“正常工作”的代码并专注于您需要处理的代码。