Multiple imports on one line frown upon? [duplicate] - python

When importing modules in Python, what is the difference between this:
from module import a, b, c, d
and this
from module import a
from module import b
from module import c
from module import d
To me it makes sense always to condense code and use the first example, but I've been seeing some code samples out there dong the second. Is there any difference at all or is it all in the preference of the programmer?

There is no difference at all. They both function exactly the same.
However, from a stylistic perspective, one might be more preferable than the other. And on that note, the PEP-8 for imports says that you should compress from module import name1, name2 onto a single line and leave import module1 on multiple lines:
Yes: import os
import sys
No: import sys, os
Ok: from subprocess import Popen, PIPE
In response to #teewuane's comment (repeated here in case the comment gets deleted):
#inspectorG4dget What if you have to import several functions from one
module and it ends up making that line longer than 80 char? I know
that the 80 char thing is "when it makes the code more readable" but I
am still wondering if there is a more tidy way to do this. And I don't
want to do from foo import * even though I am basically importing
everything.
The issue here is that doing something like the following could exceed the 80 char limit:
from module import func1, func2, func3, func4, func5
To this, I have two responses (I don't see PEP8 being overly clear about this):
Break it up into two imports:
from module import func1, func2, func3
from module import func4, func5
Doing this has the disadvantage that if module is removed from the codebase or otherwise refactored, then both import lines will need to be deleted. This could prove to be painful
Split the line:
To mitigate the above concern, it may be wiser to do
from module import func1, func2, func3, \
func4, func5
This would result in an error if the second line is not deleted along with the first, while still maintaining the singular import statement

To add to some of the questions raised from inspectorG4dget's answer, you can also use tuples to do multi-line imports when folder structures start getting deeply nested or you have modules with obtuse names.
from some.module.submodule.that_has_long_names import (
first_item,
second_item,
more_imported_items_with_really_enormously_long_names_that_might_be_too_descriptive,
that_would_certainly_not_fit,
on_one_line,
)
This also works, though I'm not a fan of this style:
from module import (a_ton, of, modules, that_seem, to_keep, needing,
to_be, added, to_the_list, of_required_items)

I would suggest not to follow PEP-8 blindly. When you have about half screen worth of imports, things start becoming uncomfortable and PEP-8 is then in conflicts with PEP-20 readability guidelines.
My preference is,
Put all built-in imports on one line such as sys, os, time etc.
For other imports, use one line per package (not module)
Above gives you good balance because the reader can still quickly glance the dependencies while achieving reasonable compactness.
For example,
My Preference
# one line per package
import os, json, time, sys, math
import numpy as np
import torch, torch.nn as nn, torch.autograd, torch.nn.functional as F
from torchvision models, transforms
PEP-8 Recommandation
# one line per module or from ... import statement
import os
import json
import time
import sys
import math
import numpy as np
import torch
from torch import nn as nn, autograd, nn.functional as F
from torchvision import models, transforms

A concern not mentioned by other answers is git merge conflicts.
Let's say you start with this import statement:
import os
If you change this line to import os, sys in one branch and import json, os in another branch, you will get this conflict when you attempt to merge them:
<<<<<<< HEAD
import os, sys
=======
import json, os
>>>>>>> branch
But if you add import sys and import json on separate lines, you get a nice merge commit with no conflicts:
--- a/foo.py
+++ b/foo.py
### -1,2 -1,2 +1,3 ###
+ import json
import os
+import sys
You will still get a conflict if the two imports were added at the same location, as git doesn't know which order they should appear in. So if you had imported time instead of json, for example:
import os
<<<<<<< HEAD
import sys
=======
import time
>>>>>>> branch
Still, it can be worth sticking with this style for the occasions where it does avoid merge conflicts.

Imports should usually be on separate lines as per PEP 8 guidelines.
# Wrong Use
import os, sys
# Correct Use
import os
import sys
For more import based PEP 8 violations and fixes please check this out https://ayush-raj-blogs.hashnode.dev/making-clean-pr-for-open-source-contributors-pep-8-style.

Both are same.
Use from module import a, b, c, d.
If you want to import only one part of a module, use:
from module import a
If u want to import multiple codes from same module, use:
from module import a,b,c,d
No need to write all in separate lines when both are same.

Related

In Python, how to import all modules from a library in one line?

The following code works:
import torch
import pytorch_lightning as torchl
import pytorch_forecasting as torchf
from pytorch_forecasting.data.examples import get_stallion_data
x = torchf.data.examples.get_stallion_data()
print(x)
However, if I remove the 4th line, I get an error:
AttributeError: module 'pytorch_forecasting.data' has no attribute 'examples'
It is tedious and ugly to devote many lines just for loading several modules from one library, like:
from pytorch_lightning.callbacks import EarlyStopping, LearningRateMonitor
from pytorch_lightning.loggers import TensorBoardLogger
from pytorch_forecasting import Baseline, TemporalFusionTransformer, TimeSeriesDataSet
from pytorch_forecasting.data import GroupNormalizer
from pytorch_forecasting.metrics import SMAPE, PoissonLoss, QuantileLoss
from pytorch_forecasting.models.temporal_fusion_transformer.tuning import optimize_hyperparameters
from pytorch_forecasting.data.examples import get_stallion_data
Is there a way to import all these modules using just one line, and then later use them as:
x=torchf.bla.bla.bla.bla(parameters)
I prefer this way also because there is less danger of name conflicts: calling x=library1.module(); y=library2.module(); avoids name clashes, unlike from library1 import *; from library2 import *; x=module(); y=module();.
To import everything from a package you can just do import pytorch_lightning and it will import all modules and files inside the package. Then you can use it as x = pytorch_lightning.callbacks.EarlyStopping().
The drawback is that you are loading files and modules(and packages that they import consecutively) that you do not necessarily require which increases the import time.

Why does python import module imports when importing *

Let's say I have a file where I'm importing some packages:
# myfile.py
import os
import re
import pathlib
def func(x, y):
print(x, y)
If I go into another file and enter
from myfile import *
Not only does it import func, but it also imports os, re, and pathlib,
but I DO NOT want those modules to be imported when I do import *.
Why is it importing the other packages I'm importing and how do you avoid this?
The reason
Because import imports every name in the namespace. If something has a name inside the module, then it's valid to be exported.
How to avoid
First of all, you should almost never be using import *. It's almost always clearer code to either import the specific methods/variables you're trying to use (from module import func), or to import the whole module and access methods/variables via dot notation (import module; ...; module.func()).
That said, if you must use import * from module, there are a few ways to prevent certain names from being exported from module:
Names starting with _ will not be imported by import * from .... They can still be imported directly (i.e. from module import _name), but not automatically. This means you can rename your imports so that they don't get exported, e.g. import os as _os. However, this also means that your entire code in that module has to refer to the _os instead of os, so you may have to modify lots of code.
If a module contains the name __all__: List[str], then import * will export only the names contained in that list. In your example, add the line __all__ = ['func'] to your myfile.py, and then import * will only import func. See also this answer.
from myfile import func
Here is the fix :)
When you import *, you import everything from. Which includes what yu imported in the file your source.
It has actually been discussed on Medium, but for simplification, I will answer it myself.
from <module/package> import * is a way to import all the names we can get in that specific module/package. Usually, everyone doesn't actually use import * for this reason, and rather sticked with import <module>.
Python's import essentially just runs the file you point it to import (it's not quite that but close enough). So if you import a module it will also import all the things the module imports. If you want to import only specific functions within the module, try:
from myfile import func
...which would import only myfile.func() instead of the other things as well.

Is there anything bad about having multiple imports on one line?

When I'm programming in Python and I need to import multiple modules, I usually do I like this:
import random, time, matplotlib, cheese, doge
Then when I read over other people's code, this is what I see:
import random
import time
import matplotlib
import cheese
import doge
Why is this? Is there any difference between the two styles?
The practice of one import per line is standardized in PEP8, and following a common standard is reason enough to do as others do. Following a common standard follows the Principle of Least Astonishment, making it easier for people familiar with the standard to read and modify your code.
Even if you don't care about PEP8, though, one import per line makes your code more maintainable.
Imports are easier to skim/read:
It's easier to see that you are getting a fred in import fred than in import barney, betty, wilma, fred, bambam, pebbles
Imports are easier to locate:
Searching for "import fred" will find import fred and import fred, wilma, pebbles, but will not find import barney, fred
Imports are easier to edit:
Inserting and removing an entire line is fast in most editors.
There is only one module per line, so you don't have to search in the line to find the thing you wish to edit - it's at the end.
Relocating an import inside a module is just moving a whole line.
Copying one of several imports to another Python module is a copy-paste of a line,
rather than that copy-paste followed by trimming off the other imports you don't want.
Imports are easier to maintain:
Each changed module has its own line in the change-set - you don't have to read a line to figure out which module or modules changed.
Missing and added modules effect the line count on the file and in the change-set.
Typos are easier to pick out and correct on visual skim of the change-set.
One import per line would be a good idea even if it weren't the standard. Since it is the standard, it's doubly the best way to go.
As per PEP-8 (The Style Guide for Python Code)
Imports should usually be on separate lines, for e.g
Yes: import os
import sys
No: import sys, os
It's okay to say this though:
from subprocess import Popen, PIPE
To answer your question - both would work fine, but one is not conformant with the PEP8 guidelines.
I don't like to follow blindly without valid reason. As PEP20: Zen of Python states that "Readability Counts"
PEP8 "single line per import" works for general perspective. Although I respect his (i.e. Guido) opinion, I wouldn't always strictly follow this conventions all the time.
The exception for this rule is only when the # of code is smaller than the # of module import. e.g. 2 lines of code, but 4 module import.
This is more readable: (in my opinion)
import os, sys, math, time
def add_special():
return time.time() + math.floor(math.pow(sys.api_version + os.getpid(), 2))
instead of this
import os
import sys
import math
import time
def add_special():
return time.time() + math.floor(math.pow(sys.api_version + os.getpid(), 2))
But this readability matter differs for each individuals.
PEP-8, the official Python style guide, mandates that one package or module should be imported per line.
It is considered good style, and generally standardization makes programs easy to read. I don't think there are substantial differences under the hood to worry about, if that's what you're asking.
Those two examples are functionally equivalent. However, PEP 8, the official style-guide for Python, has a section here that condemns the practice of placing multiple imports on one line:
Imports should usually be on separate lines, e.g.:
Yes: import os
import sys
No: import sys, os
It's okay to say this though:
from subprocess import Popen, PIPE
Thus, many Python programmers place only one import per line in order to follow this guideline.

PEP 8: How should __future__ imports be grouped?

According to PEP 8:
Imports should be grouped in the following order:
standard library imports
related third party imports
local application/library specific imports
You should put a blank line between each group of imports.
But it does not mention about __future__ imports. Should __future__ imports be grouped together with standard library imports or separated from standard library imports.
So, which is more preferred:
from __future__ import absolute_import
import sys
import os.path
from .submod import xyz
or:
from __future__ import absolute_import
import sys
import os.path
from .submod import xyz
I personally separate them. A __future__ import isn't just binding a name like other imports, it changes the meaning of the language. With things like from __future__ import division the module will likely run fine both with and without the import, but give different (wrong) results at places that have nothing telling me to go look at names imported if I want to know more about where they come from. __future__ imports should stand out as much as possible.
Also, I generally sort imports within a group alphabetically (no particularly good reason for doing that; I just find it has some very small benefits to diffs and merging branches), and __future__ imports have to be first, so I put them in their own group.

Importing modules in Python - best practice

I am new to Python as I want to expand skills that I learned using R.
In R I tend to load a bunch of libraries, sometimes resulting in function name conflicts.
What is best practice in Python. I have seen some specific variations that I do not see a difference between
import pandas, from pandas import *, and from pandas import DataFrame
What are the differences between the first two and should I just import what I need.
Also, what would be the worst consequences for someone making small programs to process data and compute simple statistics.
UPDATE
I found this excellent guide. It explains everything.
Disadvantage of each form
When reading other people's code (and those people use very
different importing styles), I noticed the following problems with
each of the styles:
import modulewithaverylongname will clutter the code further down
with the long module name (e.g. concurrent.futures or django.contrib.auth.backends) and decrease readability in those places.
from module import * gives me no chance to see syntactically that,
for instance, classA and classB come from the same module and
have a lot to do with each other.
It makes reading the code hard.
(That names from such an import
may shadow names from an earlier import is the least part of that problem.)
from module import classA, classB, functionC, constantD, functionE
overloads my short-term memory with too many names
that I mentally need to assign to module in order to
coherently understand the code.
import modulewithaverylongname as mwvln is sometimes insufficiently
mnemonic to me.
A suitable compromise
Based on the above observations, I have developed the following
style in my own code:
import module is the preferred style if the module name is short
as for example most of the packages in the standard library.
It is also the preferred style if I need to use names from the module in
only two or three places in my own module;
clarity trumps brevity then ("Readability counts").
import longername as ln is the preferred style in almost every
other case.
For instance, I might import django.contrib.auth.backends as djcab.
By definition of criterion 1 above, the abbreviation will be used
frequently and is therefore sufficiently easy to memorize.
Only these two styles are fully pythonic as per the
"Explicit is better than implicit." rule.
from module import xx still occurs sometimes in my code.
I use it in cases where even the as format appears exaggerated,
the most famous example being from datetime import datetime
(but if I need more elements, I will import datetime as dt).
import pandas imports the pandas module under the pandas namespace, so you would need to call objects within pandas using pandas.foo.
from pandas import * imports all objects from the pandas module into your current namespace, so you would call objects within pandas using only foo. Keep in mind this could have unexepcted consequences if there are any naming conflicts between your current namespace and the pandas namespace.
from pandas import DataFrame is the same as above, but only imports DataFrame (instead of everything) into your current namespace.
In my opinion the first is generally best practice, as it keeps the different modules nicely compartmentalized in your code.
Here are some recommendations from PEP8 Style Guide.
Imports should usually be on separate lines, e.g.:
Yes: import os
import sys
No: import sys, os
but it is okay to
from subprocess import Popen, PIPE
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
Imports should be grouped in the following order:
standard library imports
related third party imports
local application/library specific imports
You should put a blank line between each group of imports.
Absolute imports are recommended
They are more readable and make debugging easier by giving better error messages in case you mess up import system.
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
or explicit relative imports
from . import sibling
from .sibling import example
Implicit relative imports should never be used and is removed in Python 3.
No: from ..grand_parent_package import uncle_package
Wildcard imports ( from <module> import * ) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.
Some recommendations about lazy imports from python speed performance tips.
Import Statement Overhead
import statements can be executed just about anywhere. It's often useful to place them inside functions to restrict their visibility and/or reduce initial startup time. Although Python's interpreter is optimized to not import the same module multiple times, repeatedly executing an import statement can seriously affect performance in some circumstances.
the given below is a scenario explained at the page,
>>> def doit1():
... import string
... string.lower('Python')
...
>>> import string
>>> def doit2():
... string.lower('Python')
...
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()')
>>> t.timeit()
11.479144930839539
>>> t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()')
>>> t.timeit()
4.6661689281463623
In general it is better to do explicit imports.
As in:
import pandas
frame = pandas.DataFrame()
Or:
from pandas import DataFrame
frame = DataFrame()
Another option in Python, when you have conflicting names, is import x as y:
from pandas import DataFrame as PDataFrame
from bears import DataFrame as BDataFrame
frame1 = PDataFrame()
frame2 = BDataFrame()
from A import B
essentially equals following three statements
import A
B = A.B
del A
That's it, that is it all.
They are all suitable in different contexts (which is why they are all available). There's no deep guiding principle, other than generic motherhood statements around clarity, maintainability and simplicity. Some examples from my own code:
import sys, os, re, itertools avoids name collisions and provides a very succinct way to import a bunch of standard modules.
from math import * lets me write sin(x) instead of math.sin(x) in math-heavy code. This gets a bit dicey when I also import numpy, which doubles up on some of these, but it doesn't overly concern me, since they are generally the same functions anyway. Also, I tend to follow the numpy documentation — import numpy as np — which sidesteps the issue entirely.
I favour from PIL import Image, ImageDraw just because that's the way the PIL documentation presents its examples.

Categories