仅导入模块时的Python导入周期

时间:2015-07-10 22:42:13

标签: python import circular-dependency

我知道这个问题在这里已经被无数次询问了,但是我很长时间以来一直坚持这个问题并且无法在线找到解决方案。

我有一个导入周期,这是堆栈跟踪:

Traceback (most recent call last):
  File "openldap_lookup.py", line 2, in <module>
    import pure.directory_service.ds_lookup as dsl
  File "/home/myname/purity/tools/pure/directory_service/ds_lookup.py", line 8, in <module>
    import pure.authorization.auth as auth
  File "/home/myname/purity/tools/pure/authorization/auth.py", line 16, in <module>
    import auth_unix as auth_impl
  File "/home/myname/purity/tools/pure/authorization/auth_unix.py", line 17, in <module>
    import pure.directory_service.ad_lookup as ad_lookup
  File "/home/myname/purity/tools/pure/directory_service/ad_lookup.py", line 1, in <module>
    import pure.authorization.auth as auth
AttributeError: 'module' object has no attribute 'auth'

我只导入模块;我避开from <module> import <class>from <module> import <method>

我尝试在本地重现错误,但python没有抱怨。这些是本地测试文件:

openldap_lookup.py

import ds_lookup
def openldap_foo():
    print ds_lookup.ds_foo
print 'openldap_lookup importing ds_lookup'

ds_lookup.py

import auth as au
def ds_foo():
    print au.auth_foo
print 'ds_lookup importing auth'

auth.py

import auth_unix
def auth_foo():
    print auth_unix.auth_unix_foo
print 'auth importing auth_unix'

auth_unix.py

import ad_lookup
def auth_unix_foo():
    print ad_lookup.ad_foo
print 'auth_unix importing ad_lookup'

ad_lookup.py

import auth as au
def ad_foo():
    print au.auth_foo
print 'ad_lookup importing auth'

但是python没有抱怨:

myname@myname-mbp:~/cycletest$ python openldap_lookup.py
ad_lookup importing auth
auth_unix importing ad_lookup
auth importing auth_unix
ds_lookup importing auth
openldap_lookup importing ds_lookup
myname@myname-mbp:~/cycletest$

我不是python专家,但我知道导入周期导致错误。但是为什么小测试文件不会出现相同的错误?什么时候导入循环在python中是合法的,什么时候不合适?我该怎么做才能解决这个问题?

我非常感谢那里的python专家的帮助。

由于许多人一定要问,为什么我首先要进行这个循环?

嗯,openldap_lookup和ad_lookup都包含ds_lookup中基类的子类。 ds_lookup需要auth中的常量。 auth需要auth_unix作为实现,而auth_unix依次调用实现openldap_lookup和ad_lookup。

我很想从auth中移出常量并删除循环,但是这段代码是一个大型git repo的一部分,其中数百个文件依赖于auth中的常量和方法,我想避免重构所有这些都是可能的。

1 个答案:

答案 0 :(得分:0)

实际上,您不只是导入模块 - 您正在从软件包导入模块,而您的测试用例实际上并未反映出这一点。

我认为问题在于,在第一次导入pure.authorization.auth时,解释器仍在构建pure.authorization模块(它还没有将auth绑定到pure.authorization,因为它没有&#39 ; t完成导入auth),所以第二次遇到这个,它找到了pure.authorization模块,但是还没有全局变量auth。

就打破循环而言,auth真的需要立即导入auth_unix,还是可以延迟直到你真的需要auth实现?