gpt4 book ai didi

python - 递归导入语句

转载 作者:太空宇宙 更新时间:2023-11-03 11:13:45 24 4
gpt4 key购买 nike

我有一个关于包中递归导入语句的问题。我看到了很多关于这个主题的帖子,但我找不到可行的解决方案。我复制了一个非常小的例子来隔离我的问题。

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 类,反之亦然)。

temp 包中实现类 AB 的最佳 pythonic 方法是什么?

最佳答案

除了合并文件之外还有几个选项,您曾说过您的工作场所惯例不鼓励这样做。 (以下选项根据 this comment from Sanyash 中链接的答案针对 Python 3 进行了修改。我认为在此处包含一个答案是有意义的,因为该问题不直接与相对导入有关。)

将循环导入移动到文件末尾

文件 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 也有类似的变化。这让我觉得这是最干净的解决方案——我强烈希望尽可能将导入放在一起。 (我想不出这种方法有什么缺点,但如果有人知道任何缺点,请发表评论,我会对此进行更新。)

将导入移动到使用它们的地方

如果你只是在一个地方引用 a.py 中的 B,你可以将导入移动到需要它的函数中:

from .abstract import Abstract

class A(Abstract):
# ...

def as_b(self):
from .b import B
return B(int(self.string))

b.py 也是如此。与第一个选项相比,这有一个优势,那就是更容易看出为什么导入不在顶部,而且我觉得它不太可能导致混淆或错误。但是,它可以掩盖导入错误,因此我认为这不是理想的选择。它还会略微减慢 as_aas_b 的第一次调用,因为导入将在第一次调用每个函数时发生并且花费非零时间。

关于python - 递归导入语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55734950/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com