我在包中涉及到递归导入语句的问题。我看到了很多关于该主题的文章,但找不到有效的解决方案。我转载了一个非常小的示例来解决我的问题。
软件包中的文件组织temp
如下:
|-- __init__.py
|-- abstract.py
|-- a.py
|-- b.py
该文件__init__.py
包含
from .a import A
from .b import B
该文件abstract.py
包含
from abc import ABC, abstractmethod
class Abstract(ABC):
@abstractmethod
def __init__(self):
pass
该文件a.py
包含
from .abstract import Abstract
from .b import B
class A(Abstract):
def __init__(self, string):
super().__init__()
self.string = string
def as_b(self):
return B(int(self.string))
该文件b.py
包含
from .abstract import Abstract
from .a import A
class B(Abstract):
def __init__(self, integer):
super().__init__()
self.integer = integer
def as_a(self):
return A(str(self.integer))
然后,我创建了一个文件foo.py
来测试temp
包含以下内容的软件包
from temp import A, B
an_a = A("2")
a_b = B(4)
an_a_as_b = A.as_b()
a_b_as_a = B.as_a()
在运行时,我收到错误消息ImportError: cannot import name 'A'
。我的理解是,这是由于递归导入语句(类A导入类B,反之亦然)引起的。
什么是实现类的最佳Python的方式A
,并B
在temp
包?
除了合并文件以外,还有几种选择,您说过,您的工作场所惯例不建议使用。(下面的选项适用于来自Sanyash的此评论中链接的答案的Python 3 relative 。我认为在此处包括答案是有道理的,因为该问题并不直接与相对导入有关。)
该文件a.py
变为:
from .abstract import Abstract
class A(Abstract):
# ...
from .b import B
并b.py
以相同的方式进行更改。这是一个简单的更改,但缺点是您的进口分散。有人可能会通过将导入移到顶部来“清理”您的代码,并遇到同样的困惑。(您可以发表评论,但是人们经常会错过评论。)
您还可以让每个模块导入另一个模块,而不是从另一个模块导入。a.py
变成:
from .abstract import Abstract
from . import b
class A(Abstract):
# ...
def as_b(self):
return b.B(int(self.string)) # note the change to use b.B
当然b.py
也会发生类似的变化 这使我成为最干净的解决方案-我极力主张尽可能将进口货物保持在一起。(我认为这种方法没有任何缺点,但是如果有人知道任何方法,请发表评论,我将对此进行更新。)
如果你只是指B
从a.py
一个地方这样您可以将导入到需要的地方的功能:
from .abstract import Abstract
class A(Abstract):
# ...
def as_b(self):
from .b import B
return B(int(self.string))
和相同b.py
。与第一个选项相比,它具有一个优势,即可以更轻松地了解为什么导入不在顶部,并且我认为它不太可能导致混乱或错误。但是,它可以掩盖导入错误,所以我认为这不是理想的选择。而且,首次调用as_a
和会稍微减慢速度as_b
,因为导入将在第一次调用每个函数时发生,并且需要非零时间。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句