Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Files, folders, __init__.py, and imports
-
Apologies if this question turns out to not be Pythonista-specific, but I'm having a hard time understanding why my folders + imports break when I move things in Pythonista.
When I place foo.py somewhere in Pythonista (at the top level, or within a folder, or within a folder that contains an empty init.py, or a deeper folder) what are the rules for doing an import both (a) from foo.py, and (b) of foo.py.
Is site_packages special? Any others?
Do these rules depend on where the top-level main file being run is located?
Thanks!
-
The
import foo
statement (which internally becomesfoo = __import__("foo")
) looks through all directories listed insys.path
for a module with the namefoo
.sys.path
includes a number of internal Pythonista folders holding the standard library and extensions that come with the app, as well as the main Script Library aka. Documents folder and site-packages. Any other folder will not be searched when importing. This means that havingfoo.py
in either Documents or site-packages makes it importable, but having it in subfolders doesn't.Packages are a special type of module source. Any folder containing an
__init__.py
file is considered a package and can be imported. A package may contain any number of sub-modules and sub-packages. Say you have a folderfoo
in Documents or site-packages containing the files__init__.py
,bar.py
andspam.py
. The statementimport foo
will import the__init__.py
file as the namefoo
.import foo.bar
will first import__init__.py
to the namefoo
, then importbar.py
as the attributefoo.bar
. (i. e. importing a submodule will also import all parent modules from top to bottom.) Do note however that importing a module will normally not import any of its submodules. Some packages (such asnumpy
orsympy
) do this in their__init__.py
s for convenience, so for example writingimport numpy
will automatically give you a useful set of NumPy's modules without needing to explicitly import them.There is also a feature for imports inside packages called relative imports. For instance, in
bar.py
from our above example, we could writefrom . import spam
to importspam.py
from the current package. Unlikefrom foo import spam
this import will work no matter what you name thefoo
package. Relative imports only work in scripts that are not the main script though. Ifbar.py
containsfrom . import spam
and we doimport foo.bar
from another script, the code will run fine - but if we runbar.py
as the main script it will error because the main script is never considered part of a package. This may seem an unnecessary restriction, but is important in modules that depend on their parent packages'__init__.py
s being run beforehand.(This is a very lengthy explanation and probably more than you asked for, but hopefully it'll answer any import questions you may have ;)
-
This is a great resource. Thanks for all the detail. It demystifies much of what goes on in import.
-
Very helpful, thanks so much!