【问题标题】:Python import cycle when importing modules only仅导入模块时的 Python 导入周期
【发布时间】:2015-09-29 19:55:58
【问题描述】:

我知道这个问题在这里被问了无数次,但是我被这个问题困扰了很长时间,一直无法在网上找到解决方案。

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

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 &lt;module&gt; import &lt;class&gt;from &lt;module&gt; import &lt;method&gt;

我尝试在本地重现错误,但 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 存储库的一部分,其中数百个文件依赖于 auth 中的常量和方法,我希望避免重构如果可能,所有这些。

【问题讨论】:

    标签: python import circular-dependency


    【解决方案1】:

    实际上,您不只是导入模块——您是从包中导入模块,而您的测试用例实际上并没有反映这一点。

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

    就打破循环而言,auth 是否真的需要立即导入 auth_unix,或者可以推迟到您真正需要 auth 实现之前?

    【讨论】:

    • as auth 部分是那里的问题。删除它,它会正常工作。
    • 您是绝对正确的,更改最后一个“import pure.authorization.auth as auth”(来自 ad_lookup 的那个)可以防止错误在这里发生,但如果需要 auth,它可能会在以后发生在模块级别。例如。紧随该导入之后的“auth = pure.authorization.auth”仍然会失败。但是,如果仅在函数内部查找和使用 auth,则更改它是一种很好的方法。
    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多