Python包设计和循环导入

时间:2013-07-01 21:17:22

标签: python import system-design

我正在使用Python 3.3.2编写一个封装文件系统的包。我的项目看起来像这样:

~/
  python/
    filesystem/
      __init__.py
      file.py
      directory.py

PYTHONPATH=~/python

问题是,file.py需要directory.py(例如,File.get_directory()},directory.py需要file.py(例如Directory.get_files() }),所以我有一个循环导入。

  1. 当我使用import directory中的file.pyimport file中的directory.py时,只有当我的工作目录为filesystem时(即进口是本地的。)
  2. 当我使用import filesystem.directory中的file.pyimport filesystem.file中的directory.py时,除了写filesystem.file.File和{{1}的审美烦扰外,它的工作正常他们所有的时间。
  3. 奇怪的是,当我使用filesystem.Directory.directoryimport filesystem.directory as directory时,我收到了循环导入错误from filesystem.directory import Directory。我的猜测是,虽然'module' object has no attribute 'directory'是懒惰的,import ...import ... as会尝试评估模块并立即注意到圆形。
  4. 解决此问题的一种方法是在from ... import内部使用它的函数。不幸的是,我的许多方法都使用它,并且在类中导入它似乎不起作用。
  5. 这是可以解决的,当然:吮吸它并写import filesystem.directory;将filesystem.directory.Directory分配给__import__方法中的全局变量,以用于所有其他方法;在同一个文件中定义__init__File;等等。但这些比解决方案更妥协,所以我的问题仍然存在:

    1. 如何设计文件系统,文件类使用目录类,反之亦然?
    2. 更一般地说,您将如何处理(或避免)循环进口?
    3. 感谢。

      更新[03.07.2013] (主要是出于讨论的缘故)

      我遇到的另一个解决方案是某种前向声明,在公共头中有空Directoryfile类,后面是单独的实现(更像是属性添加)。虽然最终的设计非常简洁,但这个想法更多的是C ++ - 而不是Pythonic。

1 个答案:

答案 0 :(得分:1)

使用完全合格的路径并不是真正的黑客攻击;它可能是解决这一特定问题的正确方法。如果你想输入一个较短的名字,你可以这样做:

import filesystem.directory

class File(object):

   def __init__(self):
       self._Directory = filesystem.directory.Directory

   def foo(self):
       some_dir = self._Directory(...)

如果您正在测试等等,这也使得交换模拟变得微不足道。