在其方法和不同的文件中构造一个 Python class

Construct a Python class inside its method and different file

我想在其方法之一中从相同的 class 构造一个对象。但是,该方法在不同的文件中。 我怎样才能做到以下几点?

file1.py

class MyClass():
    def __init__(self, i): 
        print(i)
    from file2 import my_fun

file2.py

def my_fun(self):
    if i == 1:
        new_obj = MyClass(i + 1)

我收到以下错误:

NameError: name 'MyClass' is not defined

file2 必须在某处导入 file1.MyClass。在 my_fun 内导入当然是可能的,但不可取。在文件开头执行 from file1 import MyClass 会导致循环依赖问题:MyClass 可能在那个时候还没有执行,因此可能不存在。

选项 1:

import file1

def my_fun(self):
    if i == 1:
        new_obj = file1.MyClass(i + 1)

在这种情况下,file1 将引用正确的模块对象,即使此时其 __dict__ 未完全填充。到可以调用 my_fun 时,file1 已经完全加载。

选项 2:

class MyClass():
    def __init__(self, i): 
        print(i)

from file2 import my_fun
MyClass.my_fun = my_fun
del my_fun
def my_fun(self):
    if i == 1:
        new_obj = MyClass(i + 1)

from file1 import MyClass

在这个版本中,你把所有的导入语句都放在导入到另一个文件的定义之后,才有机会运行。这一点都不优雅。

选项 3

def my_fun(self):
    from file1 import MyClass
    if i == 1:
        new_obj = MyClass(i + 1)

这是所有选项中最丑陋的一个。您可以通过移除 file2file1 的依赖来移除循环依赖。该依赖关系是 my_fun 独有的,直到 运行 时间才会完全解决。这并不可怕,因为在第一次执行之后,导入基本上只是分配

MyClass = sys.modules['file1'].MyClass

TL;DR

您有几种方法可以通过仔细处理模块加载的执行路径来绕过循环依赖。但是,此处显示的所有选项都是 code smell,您应该避免使用它们。它们表明应该以其他方式解决的模块之间的耦合程度不当。