【问题标题】:Python Package Design And Circular ImportsPython 包设计和循环导入
【发布时间】:2013-06-29 03:05:55
【问题描述】:

我正在使用 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. 当我在file.py 中使用import directory 和在directory.py 中使用import file 时,它仅在我的工作目录为filesystem 时才有效(即,当导入是本地时)。
  2. 当我在file.py 中使用import filesystem.directory 和在directory.py 中使用import filesystem.file 时,它工作得很好,除了一直写filesystem.file.Filefilesystem.Directory.directory 的审美滋扰。
  3. 奇怪的是,当我使用import filesystem.directory as directoryfrom filesystem.directory import Directory 时,我收到循环导入错误'module' object has no attribute 'directory'。我的猜测是,虽然 import ... 很懒惰,但 import ... asfrom ... import 会尝试评估模块并立即注意到循环性。
  4. 解决这个问题的一种方法是在使用它的函数中import filesystem.directory。不幸的是,我的许多方法都使用它,并且在类中导入它似乎不起作用。

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

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

谢谢。

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

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

【问题讨论】:

  • 处理循环导入花了我一段时间。我真的必须(手动)将我的模块绘制成树状结构,确保我只携带我的依赖项一个方向。一旦我在做出更大的项目决策之前开始这样做,它确实减少了我以后必须进行的重构。
  • @BlackVegetable - 如果没有循环导入,您将如何设计所描述的文件系统?它在我看来本质上是圆形的,所以我很想听听一些开箱即用的替代设计。

标签: python import system-design


【解决方案1】:

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

import filesystem.directory

class File(object):

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

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

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

【讨论】:

  • 感谢您的回答。这些基本上是“把它吸起来并写filesystem.directory.Directory”和“将__import__分配给__init__方法中的全局变量以供所有其他方法使用”解决方案,我猜完全合格的路径是确实是正确的解决方案,但我仍在寻找替代方案,即使只是出于学术好奇心。
猜你喜欢
  • 1970-01-01
  • 2014-12-26
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 2010-10-19
相关资源
最近更新 更多