在导入前一个类的类中导入类(import-ception)

时间:2015-09-29 02:45:30

标签: python import

我正在尝试在名为Networking的单独python文件中编写一个名为networking.py的大类,以提供一些帮助方法。我可以在main.py中导入该类,但是,我希望我的网络类能够在main.pyMain类)中调用方法。它似乎不允许我使用:

from main import Main

我猜它会导致某种类型的import-ception悖论。那我怎么能这样做呢。我只需要在MainNetworking调用一个方法,但Main会调用Networking中的多个方法。

main.py

from networking import Networking

class Main:

    Networking.get("Test")

    def receive(st):
        print("Received : "+st)
        Networking.push(st + "123")

networking.py

class Networking:

    @staticmethod
    def get(st):
        print("Requesting parameter (" + st + ") from smartphone")
        receive(st) #method in Main

    @staticmethod
    def push(st):
        print("Sending  (" + st + ")  to smartphone")

1 个答案:

答案 0 :(得分:2)

在Python中,当您第一次导入模块(或其中的一部分)时,模块内的代码将像任何其他代码一样执行。也就是说,如果你在全局范围内存在一些print,它们将在导入时执行。

在你的情况下,当你正在运行main.py时,你的第一条指令就是导入networking,这到目前为止还不错。然后,导入networking(并读取/执行模块),网络文件的第一条指令是导入主模块。事情开始变得糟糕。 main模块尚未导入,因此它会尝试导入它,并通过这样做再次执行它。 main模块的第一条指令是从Networking模块导入networking。它现在不需要导入networking,因为它已经导入了......对吗?但是当它尝试从该模块导入Networking类时,它会失败 - 网络不存在,因为它尚未定义(记住,我们仍然没有读取/执行过去networking.py之后的任何内容第一条指令(import)。

为了更好地说明这一点,如果将Executing first line of *xxx.py*, *before/after* import添加到模块顶部(import指令之前和之后),则输出结果如下。正如您所看到的,它永远无法通过导入序列 - 您可以在尝试从Network导入networking时看到它崩溃,正如上面所解释的那样:

Executing first line of main.py, before import
Executing first line of networking.py, before import
Executing first line of main.py, before import
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    from networking import Networking
  File "D:\Users\Matt\Desktop\networking.py", line 2, in <module>
    from main import Main
  File "D:\Users\Matt\Desktop\main.py", line 2, in <module>
    from networking import Networking
ImportError: cannot import name Networking

总之,您不应该在Python中使用循环导入。重构您的模块,以便不需要循环导入。

如果你真的无法重构你的模块,那么这就是解决问题的方法。

<强> main.py

# No change here
from networking import Networking

class Main:
    Networking.get("Test")

    @staticmethod
    def receive(st):
        print("Received : "+st)
        Networking.push(st + "123")

<强> networking.py

# Define a Main class with an empty `receive` method
class Main: 
    @staticmethod
    def receive(st):
        pass

# Define your Networking class normally
class Networking: 
    @staticmethod
    def get(st):
        print("Requesting parameter (" + st + ") from smartphone")
        Main.receive(st)

    @staticmethod
    def push(st):
        print("Sending  (" + st + ")  to smartphone")

# Import your main module after `Networking` has been defined
from main import Main 

<强>输出

Requesting parameter (Test) from smartphone
Requesting parameter (Test) from smartphone
Received : Test
Sending  (Test123)  to smartphone

在定义main之后导入Networking将允许主模块中的network.Network导入工作。然后重新定义空Main类并覆盖您的假类,这允许您在最终调用Networking.get(st)时使用真正的Main类。

正如我之前所说,它有点黑客,所以你真的应该考虑重构你的模块。 ; - )