我想在同一个类的一个方法中构造一个对象。但是,该方法在另一个文件中。我该怎么做呢?
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
在这个版本中,您将所有的import语句放在导入到另一个文件的定义之后,这些定义已经有机会运行了。这一点也不优雅。
选项3
def my_fun(self):
from file1 import MyClass
if i == 1:
new_obj = MyClass(i + 1)
这是所有选项中最难看的。您可以通过移除file2
对file1
的依赖来移除循环依赖。这个依赖是my_fun
所独有的,直到运行时才会显示出来,那时它是完全可解析的。这并没有那么糟糕,因为在第一次执行之后,导入基本上只是赋值
MyClass = sys.modules['file1'].MyClass
TL;博士
你有几种绕过循环依赖的方法,只要小心地绕过模块加载的执行路径。但是,这里显示的所有选项都是代码气味,你应该避免它们。它们表明模块之间的耦合级别不合适,应该用其他方法解决。