I was looking at some code with two __import__
statements, and the second __import__
statement doesn't work unless the first one has already been run.
The directory structure is like this:
dir1
|-__init__.py
|-subdir1
| |-__init__.py
| |-file1.py
| |-file2.py
|
|-subdir2
|-__init__.py
|-file1.py
|-file2.py
The code has two __import__
statements:
m = __import__('dir1.'+subdir1, fromlist=[file1])
...
m = __import__(file2, fromlist=[class_inside_file2])
The first one makes sense - it is roughly the equivalent of doing
from dir1.subdir1 import file1
but allows for the subdirectory and file to be provided dynamically. It is the second statement that I don't understand why it works. It looks like it should be the equivalent of
from file2 import class_inside_file2
This shouldn't work as file2.py
is in subdir1
, but my current working directory is two levels above that. Additionally, all of the __init__.py
files are empty.
As you would expect, the second import statement fails with an ImportError
if it is run by itself. However, after the first import statement has run the second one works. Why?
__import__() Parameters name - the name of the module you want to import. globals and locals - determines how to interpret name. fromlist - objects or submodules that should be imported by name. level - specifies whether to use absolute or relative imports.
Using import * in python programs is considered a bad habit because this way you are polluting your namespace, the import * statement imports all the functions and classes into your own namespace, which may clash with the functions you define or functions of other libraries that you import.
Import order does not matter. If a module relies on other modules, it needs to import them itself. Python treats each . py file as a self-contained unit as far as what's visible in that file.
The Python import statement lets you import a module into your code. A module is a file that contains functions and values that you can reference from your program. The import statement syntax is: import modulename.
It turns out the explanation is rather dumb. file1
modifies sys.path
to add subdir1
to the path. With subdir1
on the path, it can obviously find file2
directly without having specify any packages.
Moral of the story - side effects (like things happening when you import a module) are dumb because it can frequently cause issues that seem bizarre and can be hard to diagnose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With