首页 > 解决方案 > 具有 classmethod 的本地类不起作用,但导入的版本有效

问题描述

我正在创建一个经理 - 成员对,分别是 Mgr 和 Mem。Mgr 类通过在init期间调用 Mem.set_manager(self) 来设置对自身的引用。如果两个类都被导入,这会成功,但在 Mem 的自检执行中会失败。我的问题 - 这里给出了什么?我当前的解决方法 - 在 Mgr 创建 (Mem.set_mgr(mgr1)) 之后显式执行类方法。

独立运行 test_class_set_mem.py 的输出:

set_mgr called
mgr is NOT set
Setting explicitly from class
set_mgr called
mgr is set

代码:test_class_set_mgr.py

# test_class_set_mgr.py
# Setting class variable
from test_class_set_mem import Mem

class Mgr:
    def __init__(self):
        Mem.set_mgr(self)    # Set communication link
        

代码:test_class_set_mem.py

# test_class_set_mem.py
# Setting class variable

class Mem:
    mgr = None      # Required mgr reference
    @classmethod
    def set_mgr(cls, mgr):
        cls.mgr = mgr
        print("set_mgr called")
    
    def __init__(self):
        if Mem.mgr is None:
            print("mgr is NOT set")
        else:
            print("mgr is set")

if __name__ == "__main__":
    from test_class_set_mgr import Mgr
    
    mgr1 = Mgr()    # set_mgr called from __init__
    mem1 = Mem()
    print("Setting explicitly from class")
    Mem.set_mgr(mgr1)
    mem2 = Mem()

代码,导入两个类都有效:

# test_class_set3.py
# Setting class variable

from test_class_set_mem import Mem            
from test_class_set_mgr import Mgr

mgr1 = Mgr()
mem1 = Mem()

运行 test_class_set3.py 的输出

set_mgr called
mgr is set

标签: pythonimport

解决方案


这是由于循环导入而发生的。该文件test_class_set_mgr.py从. Mem_ test_class_set_mem_ test_class_set_mem.py_Mgrtest_class_set_mgr

结果,当您 self-execute 时test_class_set_mem.py,该类的代码会Mem以不同的模块名称运行两次。首先,它作为__main__模块中的对象执行。然后,当线

from test_class_set_mem import Mem

达到它作为test_class_set_mem 模块的一部分再次执行。实际上,Mem用于实例化Mgr类的类与用于创建类实例的Mem类不同。 您可以通过比较andMem使用的类的id 来检查它:Mgr.__init__()Mem.__init__()

test_class_set_mgr.py:

# test_class_set_mgr.py
# Setting class variable
from test_class_set_mem import Mem

class Mgr:

    def __init__(self):
        print(f"In Mgr.__init__(). Mem class id:  {id(Mgr)}")
        Mem.set_mgr(self)    # Set communication link

test_class_set_mem.py:

# test_class_set_mem.py
# Setting class variable

class Mem:

    mgr = None      # Required mgr reference
    @classmethod
    def set_mgr(cls, mgr):
        cls.mgr = mgr
        print("set_mgr called")
    
    def __init__(self):
        print(f"In Mem.__init__(). Member class id: {id(self.__class__)}")
        if Mem.mgr is None:
            print("mgr is NOT set")
        else:
            print("mgr is set")

if __name__ == "__main__":
    from test_class_set_mgr import Mgr
    

    mgr1 = Mgr()    # set_mgr called from __init__
    mem1 = Mem()

输出:

In Mgr.__init__(). Mem class id:  140527440788784
set_mgr called
In Mem.__init__(). Mem class id: 140527440785216
mgr is NOT set

结果是代码mgr1 = Mgr()设置了mgr一个类的属性Mem,但mem1 = Mem()使用了另一个Mem类,它没有设置这个属性。


推荐阅读