3

我正在使用 Python 3.3.2 编写一个封装文件系统的包。我的项目如下所示:

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

PYTHONPATH=~/python.

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

  1. 当我使用import directoryinfile.pyimport filein 时directory.py,它仅在我的工作目录为filesystem(即,当导入为本地时)时才有效。
  2. 当我使用import filesystem.directoryinfile.pyimport filesystem.filein 时directory.py,它工作得很好,除了写作filesystem.file.Filefilesystem.Directory.directory所有时间的审美滋扰。
  3. 奇怪的是,当我使用import filesystem.directory as directoryor时from filesystem.directory import Directory,我得到了循环导入错误'module' object has no attribute 'directory'。我的猜测是 whileimport ...是懒惰的,import ... asfrom ... import尝试评估模块并立即注意到循环性。
  4. 解决这个问题的一种方法是import filesystem.directory在使用它的函数内部。不幸的是,我的许多方法都使用它,并且在类中导入它似乎不起作用。

当然,这是可以解决的:吸收它并写作filesystem.directory.Directory;在方法中分配__import__一个全局变量以__init__供所有其他方法使用;定义FileDirectory在同一个文件中;等等。但这些妥协多于解决方案,所以我的问题仍然存在:

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

谢谢。

更新 [03.07.2013](主要是为了讨论)

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

4

1 回答 1

1

使用完全合格的路径并不是真正的 hack。这可能是这个特定问题的正确解决方案。如果您想输入一个较短的名称,您可以执行以下操作:

import filesystem.directory

class File(object):

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

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

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

于 2013-07-01T21:25:59.897 回答