我想将不同类中的代码分开并将它们放到不同的文件中。但是这些课程彼此依赖。
main.py:
from lib import A, B
def main():
a = A()
b = B()
a.hello()
b.hello()
if __name__ == '__main__':
main()
LIB / _ 初始化 _吡啶:
from a import A
from b import B
LIB / a.py:
import lib.B
class A():
def __init__(self):
print "A"
def hello(self):
print "hello A"
b = B()
LIB / b.py:
import lib.A
class B():
def __init__(self):
print "B"
def hello(self):
print "hello B"
a = A()
是否可以在Python中执行此操作?
修改
我收到此错误消息:
pydev debugger: starting
Traceback (most recent call last):
File "eclipse-python/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1397, in <module>
debugger.run(setup['file'], None, None)
File "eclipse-python/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1090, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "main.py", line 2, in <module>
from lib import A, B
File "lib/__init__.py", line 1, in <module>
from a import A
File "lib/a.py", line 1, in <module>
import lib.B
ImportError: No module named B
答案 0 :(得分:16)
您可以在hello函数中导入另一个模块,而不是在顶部导入模块。
class B():
def __init__(self):
print "B"
def hello(self):
import lib.A
print "hello B"
a = A()
答案 1 :(得分:7)
当你有两个相互依赖的类时,通常意味着它们实际上属于同一个模块,或者你有一个太紧的耦合,应该使用依赖注入解决。
现在确实存在几个极端情况,从函数中导入是“最差”解决方案,但这仍然是你应该尽可能避免的事情。
答案 2 :(得分:5)
您的主要问题是您尝试导入类,但使用的语法仅用于导入模块。具体来说,如果import lib.A
是模块A
中定义的类(并导入lib.a
的顶级命名空间),则lib
永远不会起作用。
我建议您除非确实需要,否则请避免使用from _ import _
语法。这使得依赖关系更容易解决:
lib/a.py
:
import lib.b # note, we're not importing the class B, just the module b!
class A():
def foo(self):
return lib.b.B() # use the class later, with a qualified name
lib/b.py
:
import lib.a # again, just import the module, not the class
class B():
def foo(self):
return lib.a.A() # use another qualified name reference
lib/__init__.py
:
from a import A # these imports are fine, since the sub-modules don't rely on them
from b import B # they can be the public API for the A and B classes
如果您不希望a
和b
依赖于其包lib
的名称,您也可以使用相对模块导入。
这肯定有效,因为A类或B类实际上都不需要另一个存在才能被定义。只有在它们被导入之后,A的实例才需要知道B类(反之亦然)。
如果其中一个类继承自另一个类,或者在顶层使用另一个类的实例,则需要更加小心首先加载哪个模块,否则它可能仍会中断。
答案 3 :(得分:1)
如果只想导入一次,可以在类的构造函数中导入它并使变量成为全局变量:
class B():
def __init__(self):
global A
from lib import A
print "B"
def hello(self):
print "hello B"
a = A()
这会将A导入到一个全局变量中,并使其在模块中可以访问。