Infinite loop with Python imports; looking for Pythonic way

若如初见. 提交于 2020-07-09 05:35:03

问题


My team is working on huge project with Django. For sake of simplicity, here's plain Python to illustrate the problem (original problem has models and apps instead of classes (I know that both are classes) and packages (I know that both are packages as well)).

a.py:

from b import B1


class A1(object):
    def __init__(self):
        print "object A1"


class A2(object):
    def __init__(self):
        print "object A2"


A1()
B1()

b.py:

from a import A2


class B1(object):
    def __init__(self):
        print "object B1"


A2()

When a.py is called, it tries to import B1 from b package which, on the other hand, tries to import A2 from a package and then, from start, that repeats forever. Python says:

[dagrevis@localhost recursion]$ python2 a.py
Traceback (most recent call last):
  File "a.py", line 1, in <module>
    from b import B1
  File "/home/dagrevis/Python/recursion/b.py", line 1, in <module>
    from a import A2
  File "/home/dagrevis/Python/recursion/a.py", line 1, in <module>
    from b import B1
ImportError: cannot import name B1

One of the solutions would be to have one file per object. Something like C++ or Java has. Then I remembered what Guido said about Python: “Don't write Java (or C++, or Javascript, ...) in Python.“. Are there more Pythonic way to deal with this problem?

Thanks in any advice!


回答1:


Your use-case is not "solvable". You can turn the ImportError into an AttributeError importing the module a(and b) instead of importing the objects, but this does not change the fact that you wont be able to use these modules.

The problem is that your module a requires to completely execute b before being imported, but also b requries a to be completely executed before being imported.

This is simply impossible to solve, and it's a clear symptom that a refactoring is needed: your a and b modules should be a single module(or you may want to do some deeper refactoring).

edit: actually you may be able to solve this, even though I think it's quite ugly to do, putting the imports at the end of the file, when they are required. But I think this would be just a patch for some bigger problem.




回答2:


Your example is overly simplified -- it does not explain why the cyclical import is necessary. But anyway, here is one way to refactor it to runnable code:

a.py:

class A1(object):
    def __init__(self):
        print "object A1"


class A2(object):
    def __init__(self):
        print "object A2"

b.py:

class B1(object):
    def __init__(self):
        print "object B1"

c.py:

from a import A1, A2
from b import B1

A1()
A2()
B1()


来源:https://stackoverflow.com/questions/12474374/infinite-loop-with-python-imports-looking-for-pythonic-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!