Google Python Style Guide says:
Do not use relative names in imports. Even if the module is in the same package, use the full package name. This helps prevent unintentionally importing a package twice.
What would be a sample setup that incurs importing a package twice?
This is a reference to the Python 2 behavior (deprecated since 2.6) of implicit relative imports: allowing import bar
in a module in a package foo
to refer to the module foo.bar
. Consider a directory on sys.path
that looks like
…
|-- client.py
`-- pkg
|-- __init__.py
|-- mod.py
`-- script.py
with files having the following contents:
client.py
print "client..."
from pkg import mod,script
print "client!"
pkg/__init__.py
print "pkg"
pkg/mod.py
print "mod: %r"%__name__
pkg/script.py
print "script:",__name__,__package__
if __name__=='__main__':
import mod,client
print "script!"
In this setup mod
can easily be imported twice:
$ PYTHONPATH=… python …/pkg/script.py
script: __main__ None
mod: 'mod'
client...
pkg
mod: 'pkg.mod'
script: pkg.script None
client!
script!
In an attempt to reduce configuration overhead, Python adds the directory pkg
to sys.path
, effectively presuming that script.py
is a top-level module script
. Unfortunately, that means that import mod
creates a top-level module named mod
, and the explicit import of pkg.mod
later causes another copy of it to exist with its full name (just after importing pkg
itself).
It was recognized that this poses a problem, and later -m
was adjusted to tell the module being executed about the package in which it was found so that relative imports (implicit or explicit) work properly:
$ PYTHONPATH=… python -m pkg.script
pkg
script: __main__ pkg
mod: 'pkg.mod'
client...
script: pkg.script None
client!
script!
Note that pkg
is now imported first (by -m
itself!), that script
now has a __package__
attribute immediately afterwards, and that mod
is imported just once. Of course, script
itself is (still) loaded twice, since its name gets replaced with __main__
the first time so that from pkg import script
finds it under a different name.
The moral is that implementing "a module can also be a script" in terms of __name__=='__main__'
is fundamentally broken (and replacements have been rejected): a module already has a __name__
, and creating a separate module object to be the entry point so that its __name__
can differ is as absurd as copying the Java class (and all its static data) that provides main
. Making a module that no one ever imports works, but is oxymoronic (and breaks code inspection that imports all members of a package).