在python中简单交叉导入

ts_*_*ati 16 python import cross-reference

我想将不同类中的代码分开并将它们放到不同的文件中.但是这些课程相互依赖.

main.py:

from lib import A, B

def main():
    a = A()
    b = B()
    a.hello()
    b.hello()

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

lib/_ init _.py:

from a import A
from b import B
Run Code Online (Sandbox Code Playgroud)

LIB/a.py:

import lib.B

class A():
    def __init__(self):
        print "A"

    def hello(self):
        print "hello A"
        b = B()
Run Code Online (Sandbox Code Playgroud)

LIB/b.py:

import lib.A

class B():
    def __init__(self):
        print "B"

    def hello(self):
        print "hello B"
        a = A()
Run Code Online (Sandbox Code Playgroud)

是否有可能在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
Run Code Online (Sandbox Code Playgroud)

Mic*_*arf 20

您可以在hello函数中导入其他模块,而不是在顶部导入模块.

class B():
    def __init__(self):
        print "B"

    def hello(self):
        import lib.A
        print "hello B"
        a = A()
Run Code Online (Sandbox Code Playgroud)

  • 可以为全班制作这样的导入,还是在我需要lib.A的每种方法中都这样做? (2认同)

Blc*_*ght 8

您的主要问题是您正在尝试导入类,但使用的语法仅适用于导入模块.具体来说,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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

如果您不想要a并且b依赖于其包的名称,您也可以使用相对模块导入lib.

这肯定有效,因为A类或B类实际上都不需要另一个存在才能被定义.只有在它们被导入之后,A的实例才需要知道B类(反之亦然).

如果其中一个类继承自另一个类,或者在顶层使用另一个类的实例,则需要更加小心首先加载哪个模块,否则它可能仍会中断.


bru*_*ers 7

当你有两个彼此依赖的类时,通常意味着它们真的属于同一个模块,或者你有一个太紧的耦合,应该使用依赖注入解决.

现在确实存在一些极端情况,其中从函数内部导入是"最差"解决方案,但这仍然是您应该尽可能避免的.