我有以下模块:
# module 1
from abc import ABC
from module3 import AnotherClass
class Parent(ABC):
@classmethod
def func1(cls):
other_param = "foo"
AnotherClass.some_func(cls, other_param)
# module 2
from module1 import Parent
from module3 import AnotherClass
class Child1(Parent):
pass
class Child2(Parent):
pass
# module 3
from module1 import Parent # only for type checking
class AnotherClass(object):
@classmethod
def some_func(cls, child_cls, other_param):
assert issubclass(child_cls, Parent)
# do other stuff
现在,如果我这样做:
c1 = Child1()
c1.func1()
我正确地从循环导入中收到了一个ImportError抱怨,如下所示:
ImportError:无法从部分初始化的名称中导入名称“父母” 模块“ module1”(很可能是由于循环导入)
Actually AnotherClass
does not depend on Parent
or any of the Child classes, I'm importing the Parent
only for type checking in assertion at this row:
assert issubclass(child_cls, Parent)
Now, I can defer importing of the Parent
like this:
# module 3
class AnotherClass(object):
@classmethod
def some_func(cls, child_cls, other_param):
from module1 import Parent # only for type checking
assert issubclass(child_cls, Parent)
# do other stuff
它就像一种魅力。但是由于某种原因(我不知道),我以这种方式感到不舒服。
现在我的问题是,我是否可以安然入睡,推迟这样的进口,否则以后会以某种方式咬我吗?
If yes, how would you suggest I do the type checking at AnotherClass.some_func()
?
P.S. Before anyone brings it up, I know this topic of circular dependencies has been asked and answered many many times (such as this one), but I'm asking if this specific solution is feasible and problem-free in the long run.
First of all, you are not really doing "type checking" there,
assert
s are a completely different thing, since they are actually processed at run time.我认为最好使用实际的类型提示,并且通过使用它们,有一种非常简单且惯用的方式来避免循环导入问题: