I'm taking my first stab at a library, and I've noticed the easiest way to solve the issue of intra-library imports is by using constructions like the following:
from . import x
from ..some_module import y
Something about this strikes me as 'bad.' Maybe it's just the fact that I can't remember seeing it very often, although in fairness I haven't poked around the guts of a ton of libraries.
Just wanted to see if this is considered good practice and, if not, what's the better way to do this?
import Python: Using the from Statement The import statement allows you to import all the functions from a module into your code. Often, though, you'll only want to import a few functions, or just one. If this is the case, you can use the from statement.
The difference between import and from import in Python is: import imports the whole library. from import imports a specific member or members of the library.
The from keyword is used to import only a specified section from a module.
There is a PEP for everything.
Quote from PEP8: Imports
Explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose:
Guido's decision in PEP328 Imports: Multi-Line and Absolute/Relative
Here's a sample package layout:
package/
__init__.py
subpackage1/
__init__.py
moduleX.py
moduleY.py
subpackage2/
__init__.py
moduleZ.py
moduleA.py
Assuming that the current file is either moduleX.py
or subpackage1/__init__.py
, the following are all correct usages of the new syntax:
from .moduleY import spam
from .moduleY import spam as ham
from . import moduleY
from ..subpackage1 import moduleY
from ..subpackage2.moduleZ import eggs
from ..moduleA import foo
from ...package import bar
from ...sys import path
Explicit is better than implicit. At least according to the zen of python.
I find using . based imports to be confusing especially if you build or work in lots of libraries. If I don't know the package structure by heart its going to be less obvious where something comes from this way.
If someone wants to do something similar to (but not the same as) what I'm doing inside one of my library's modules, if the full package structure is specified in the import, people can copy and paste the import line.
Refactoring and restructuring are more difficult with dots because they will mean something different if you move a module around in a package structure or if you move a module to a different package.
If you want convenient access to something in your package, its likely other people do to, so you might as well solve that problem by building a good library rather than leaning on the language to keep your import lines under 80 characters. In these cases, if you have a package mypackage
with sub package stuff
with module things
and class Whatever
needs to be imported frequently in your code and users code, you can put an import in to the __init__.py
for mypackage
:
__all__ = ['Whatever']
from mypackage.stuff.things import Whatever
and then you and anyone else who wants to use Whatever
can just do:
from mypackage import Whatever
But getting less verbose or less explicit than that will more than likely cause you or someone else difficulty down the line.
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