【问题标题】:Trouble with importing in Python在 Python 中导入时遇到问题
【发布时间】:2019-10-11 19:12:11
【问题描述】:

我正在尝试创建一个需要来自主类的变量的模块,因此我将所述变量导入到模块中,但是当我尝试通过将其导入主类来测试我的新模块时,它说它可以'不要导入它。

这似乎是因为我在新模块中导入了导致问题的主类,因为每当我删除导入时,它都可以工作,但它不能再访问主类中运行所需的变量。

主类:

from Mod import Mod

variable1=5
variable2=3

mod=Mod()

mod.task()

新模块:

from Main import variable1, variable2

class Mod:
    def task(self):
        print(variable1+variable2)

当我运行主类时,我得到了这个:

Traceback (most recent call last):
  File "D:\.here\Computer Science\Computer Science Stuff\Python Projects\Main.py", line 1, in <module>
    from Mod import Mod
  File "D:\.here\Computer Science\Computer Science Stuff\Python Projects\Mod.py", line 1, in <module>
    from Main import variable1, variable2
  File "D:\.here\Computer Science\Computer Science Stuff\Python Projects\Main.py", line 1, in <module>
    from Mod import Mod
ImportError: cannot import name 'Mod' from 'Mod' (D:\.here\Computer Science\Computer Science Stuff\Python Projects\Mod.py)

当我运行新模块时,我得到了这个:

Traceback (most recent call last):
  File "D:\.here\Computer Science\Computer Science Stuff\Python Projects\Mod.py", line 1, in <module>
    from Main import variable1, variable2
  File "D:\.here\Computer Science\Computer Science Stuff\Python Projects\Main.py", line 1, in <module>
    from Mod import Mod
  File "D:\.here\Computer Science\Computer Science Stuff\Python Projects\Mod.py", line 1, in <module>
    from Main import variable1, variable2
ImportError: cannot import name 'variable1' from 'Main' (D:\.here\Computer Science\Computer Science Stuff\Python Projects\Main.py)

我不知道为什么会发生这种情况。这与我在 Java 中所做的相矛盾。

如果不通过导入,我如何能够引用存储在主类中的全局变量?

【问题讨论】:

  • 问题的根源可能是递归导入。你不应该让两个文件相互导入
  • @JammyDodger 你的意思是循环进口吗?

标签: python python-3.x import python-import


【解决方案1】:

您在此处的问题称为“circular dependency”。 Main.py 正在尝试从 Mod.py 导入一个类,但在此之前,Mod 必须从 Main.py 导入一些变量,但在此之前...

通常,解决循环依赖的方法是重新组织程序的布局方式。例如,您可以对 Mod 进行参数化,使其不再依赖于 Main。例如:

Main.py:

from Mod import Mod

variable1=5
variable2=3

mod=Mod()

mod.task(variable1, variable2)

Mod.py:

class Mod:
    def task(self, a, b):
        print(a + b)

或者,您可以将variable1variable2 存储在不同的文件中。找到最佳解决方案将取决于什么对您的程序最有意义。

【讨论】:

    【解决方案2】:

    你可以更新 Mod.task() 来接收两个额外的参数,所以你会得到:

    def task(self, a, b):
        print(a + b)
    

    然后,主要的,你会简单地说:

    mod.task(variable1, variable2)
    

    除了将 Mod 导入主类之外,无需导入

    【讨论】:

      【解决方案3】:

      这是由循环依赖引起的

      正如上面回答中提到的,解决循环依赖的方法是重新组织你的程序的布局方式。 使用 参数

      不过,一个简单的解决方法是制作内联导入

      Main.py

      from Mod import Mod
      
      variable1=5
      variable2=3
      
      mod=Mod()
      
      mod.task()
      

      Mod.py

      
      class Mod:
          def task(self):
              from Main import variable1, variable2
              print(variable1+variable2)
      

      【讨论】:

      • 虽然这段代码会运行,但循环依赖仍然存在:两个模块仍然可以相互导入,这会导致意外行为。您的代码实际上打印了两次答案(!):一次是从 Mod 导入 Main,一次是从实际运行 Main。
      【解决方案4】:

      遵循 DRY 原则。不要重复自己。

      将“主要”变量导入 Mod 会导致循环依赖。您必须不惜一切代价避免的事情。使用面向对象编程来解决您的问题。

      解决问题的步骤:

      1. 删除 Main 的导入。
      2. 更改任务函数以允许传递两个参数。应该是这样的

        def task(self, variable1, variable2):
           print(variable1 + variable2)
        

        #变量1和2可以任意命名

      3. 在主脚本上,只需调用函数:

        Mod.task(variable1, variable2)
        

        这里你必须使用变量的名字,因为你现在调用的是你在 Main 中给出的定义。

      【讨论】:

        【解决方案5】:

        我不明白你在 Java 中是什么意思这样的事情可以做.. 但是在 python 中,遵守循环引用模块的主体必须能够在不访问其他涉及的模块内容的情况下执行的规则是有可能的。
        所以你可以这样做:

        # cat Main.py
        import Mod
        var1=2
        var2=3
        if __name__ == '__main__':
            mod=Mod.Mod()
            mod.task()
        
        # cat Mod.py
        import Main
        class Mod(object):
            def task(self):
                print(Main.var1+Main.var2)
        

        例如。或者使用导入链成功后调用的函数来处理模块的初始化。
        无论如何,大多数时候最好避免这样的事情,而只是初始化你的类并使用参数调用函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-23
          • 1970-01-01
          • 2015-10-23
          • 2011-01-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多