我知道这个问题在这里已经被无数次询问了,但是我很长时间以来一直坚持这个问题并且无法在线找到解决方案。
我有一个导入周期,这是堆栈跟踪:
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中的常量和方法,我想避免重构所有这些都是可能的。
答案 0 :(得分:0)
实际上,您不只是导入模块 - 您正在从软件包导入模块,而您的测试用例实际上并未反映出这一点。
我认为问题在于,在第一次导入pure.authorization.auth时,解释器仍在构建pure.authorization模块(它还没有将auth绑定到pure.authorization,因为它没有&#39 ; t完成导入auth),所以第二次遇到这个,它找到了pure.authorization模块,但是还没有全局变量auth。
就打破循环而言,auth真的需要立即导入auth_unix,还是可以延迟直到你真的需要auth实现?