Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python from...import advice needs concrete example #52

Open
mwchase opened this issue Jan 25, 2016 · 1 comment
Open

Python from...import advice needs concrete example #52

mwchase opened this issue Jan 25, 2016 · 1 comment

Comments

@mwchase
Copy link

mwchase commented Jan 25, 2016

The from...import section of the Python style guide says:

Rationale: This is the single best -- and easiest -- way to avoid the circular-import problem. To simplify, when you say import x, Python executes the x.py file, but doesn't need to get any attributes from it. When you say from x import foo, Python needs x.py to be executed enough that foo is defined in it. When x does a 'from-import' from y, and y does a 'from-import' from x, the circular import can succeed if a partial module is enough (as it will be with import x), but it can fail if the circularity happens before the needed attribute is defined (as it might be with from x import foo).

I had trouble proving this to myself with manual testing; I think this section could really benefit from a link to some concrete example code that showcases a successful example of this behavior.

@xymostech
Copy link
Contributor

If I make these two files:

# a.py:
from b import b_test

def a_test():
    return 1
# b.py
from a import a_test

def b_test():
    return a_test()

then running import a gives an error:

>>> import a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "a.py", line 1, in <module>
    from b import b_test
  File "b.py", line 1, in <module>
    from a import a_test
ImportError: cannot import name a_test

Instead, if I do what the style guide suggests:

# a.py
import b

def a_test():
    return 1
# b.py
import a

def b_test():
    return a.a_test()

then import a works fine, as does import b; b.b_test(). Since the first way is trying to access properties of the module before it has been defined, it fails. The second way just imports the modules and uses the properties later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants