【问题标题】:Python 3.4 - Class from another module causes error when used as module-level variable or class-level variablePython 3.4 - 来自另一个模块的类在用作模块级变量或类级变量时会导致错误
【发布时间】:2016-06-27 18:17:58
【问题描述】:

在 Python 3.4(我的操作系统是 Ubuntu/Linux 14.04)中,我有一个包含许多模块的包。其中一些模块相互依赖(模块 A 使用模块 B 中的对象,模块 B 使用模块 A 中的对象)。我可以通过将import Package.A 放在模块B 的顶部和import Package.B 放在模块A 的顶部来管理循环导入。通过使用类的完整包路径执行对来自另一个模块的类的模块内调用,如x = Package.A.SomeClass()。

我在以下两种情况下遇到问题:

案例 1:当模块 B 调用模块 A 中的类以在模块 B 中定义模块级变量时。

案例 2:当模块 B 调用模块 A 中的类来定义模块 B 中的类级变量时。

我想了解为什么 Package.A.SomeClass() 在某些情况下有效而在其他情况下无效。

我在下面复制了一个非常简化的代码版本(我的真实代码可以包含来自 3 或 4 个模块的依赖项)。

我的包裹结构:

/home/phodor/test.py

/home/phodor/MInventory
/home/phodor/MInventory/__init__.py (empty file)
/home/phodor/MInventory/MProducts.py
/home/phodor/MInventory/MStores.py

一般情况:以下效果很好

/home/phodor/MInventory/MProducts.py

import MInventory.MStores

class MRobot():
   def __init__(self):   
      self.Price = 0
      self.Weight = 0

/home/phodor/MInventory/MStores.py

import MInventory.MProducts

class MCommercialCenterStore():    
   def __init__(self):       
      self.Name = ""
      self.CommercialCenter = ""
      self.Products = []
      self.MostSoldProduct = MInventory.MProducts.MRobot()

/home/phodor/test.py

import sys
sys.path.append("/home/phodor/")

from MInventory.MProducts import *
from MInventory.MStores import *

oStore = MCommercialCenterStore()
oStore.Name = "Main Street SuperCenter"
print(oStore.Name)
print(oStore.MostSoldProduct)   

案例 1:以下产生错误。

/home/phodor/MInventory/MStores.py

import MInventory.MProducts

CustomersChoice = MInventory.MProducts.MRobot

class MCommercialCenterStore():    
    def __init__(self):       
        self.Name = ""
        self.CommercialCenter = ""
        self.Products = []
        self.MostSoldProduct = CustomersChoice

错误:

CustomersChoice = MInventory.MProducts.MRobot
AttributeError: 'module' object has no attribute 'MProducts'

案例 2:以下也会产生错误。

/home/phodor/MInventory/MStores.py

class MCommercialCenterStore():
   MostSoldProduct = MInventory.MProducts.MRobot
   def __init__(self):   
      self.Name = ""
      self.CommercialCenter = ""
      self.Products = []

错误:

MostSoldProduct = MInventory.MProducts.MRobot
AttributeError: 'module' object has no attribute 'MProducts'

循环依赖信息

如前所述,我的包包含循环依赖项。到目前为止,解决这个问题的唯一方法是在我的包模块的开头使用以下语句:

import MInventory.Mproducts      ----> in the MStores module
import MInventory.MStores        ----> in the MProducts module

由于循环依赖,使用以下语句会导致错误:

from MInventory import MProducts
from MInventory import MStores

ImportError: cannot import name 'MProducts'

知道为什么MInventory.MProducts.MRobot 可以在一般情况下正确调用,为什么它在作为模块级变量或类级变量调用时不起作用?

【问题讨论】:

    标签: python-3.x import package global-variables class-variables


    【解决方案1】:

    我认为错误是python不能区分模块名称和您要使用的函数或类的名称!

    这个问题很常见,但它可以以多种不同的形式出现。在这里,您尝试进入一个名为MInventory 的文件。该文件不存在,因此也没有模块。这就产生了问题。

    也可能是您必须以另一种方式导入您的模块。试试:

          from MInventory import *
    

    或

          from MInventory import (MProducts, MStores)
    

    我已经尝试过其他代码示例,并且效果很好。如果它不起作用,我也不知道它会是什么。

    真诚的,heureka

    【讨论】:

    • 我之前尝试过这些语句。但是通过在运行中使用“from MInventory import MStores”回到循环依赖问题,我得到以下错误:“ImportError: cannot import name 'MStores'”。解决模块中的循环依赖关系的唯一方法是在我想从 MProducts 调用类时使用 import MInventory.MProducts 并使用完整路径表示法,例如 MInventory.MProducts.MRobot。这很烦人,因为完整的路径符号在类函数中可以正常工作,但在此之外的任何地方都会导致“模块没有属性”错误。
    • 所以恐怕没有我知道的解决方案! :-(
    猜你喜欢
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多