Use 'Import Module' or 'From Module Import'

Use 'import module' or 'from module import'?

The difference between import module and from module import foo is mainly subjective. Pick the one you like best and be consistent in your use of it. Here are some points to help you decide.

import module

  • Pros:

    • Less maintenance of your import statements. Don't need to add any additional imports to start using another item from the module
  • Cons:

    • Typing module.foo in your code can be tedious and redundant (tedium can be minimized by using import module as mo then typing mo.foo)

from module import foo

  • Pros:

    • Less typing to use foo
    • More control over which items of a module can be accessed
  • Cons:

    • To use a new item from the module you have to update your import statement
    • You lose context about foo. For example, it's less clear what ceil() does compared to math.ceil()

Either method is acceptable, but don't use from module import *.

For any reasonable large set of code, if you import * you will likely be cementing it into the module, unable to be removed. This is because it is difficult to determine what items used in the code are coming from 'module', making it easy to get to the point where you think you don't use the import any more but it's extremely difficult to be sure.

“from module import *” VS “import module”

PEP 8 states that

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. There is one defensible use
case for a wildcard import, which is to republish an internal
interface as part of a public API (for example, overwriting a pure
Python implementation of an interface with the definitions from an
optional accelerator module and exactly which definitions will be
overwritten isn't known in advance).

Is it more efficient to use import module or from module import func?

There is no difference on the import, however there is a small difference on access.

When you access the function as

re.findall() 

python will need to first find the module in the global scope and then find findall in modules dict. May make a difference if you are calling it inside a loop thousands of times.

Why does python import module imports when importing *

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:

  1. 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.

  2. 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.

what is the difference between importing the whole module or importing a certain function?

If you use timeit to test them:

import timeit

print(timeit.Timer('''
from tkinter import ttk
''').timeit())
# 0.47940059999999995

print(timeit.Timer('''
import tkinter
''').timeit())
# 0.09511329999999996

import the full module would be faster than only import specific module.

The memory usage of them(tested by memory_profiler):

from tkinter import ttk


Line # Mem usage Increment Line Contents
================================================
1 18.719 MiB 18.719 MiB @profile
2 def test():
3 21.297 MiB 2.578 MiB from tkinter import ttk
(>2.6)

And:

import tkinter

Line # Mem usage Increment Line Contents
================================================
1 18.676 MiB 18.676 MiB @profile
2 def test():
3 21.070 MiB 2.395 MiB import tkinter
(<=2.5M)

If you only import specific attribute.It would be faster(a little) than import the full module:

import timeit

print(timeit.Timer('''
math.sqrt(4)
''', setup="import math").timeit())
# 0.10590600000000006

print(timeit.Timer('''
sqrt(4)
''', setup="from math import sqrt").timeit())
# 0.08237790000000011

Use from tkinter import ttk just for convenience.if we want to use some sub-attribute, we don't need to type the full module name.You could learn more differences on the question.

PS: I think this overhead is not a big problem.

from ... import OR import ... as for modules

Assuming that bar is a module or package in foo, there is no difference*, it doesn't matter. The two statements have exactly the same result:

>>> import os.path as path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/posixpath.pyc'>
>>> from os import path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/posixpath.pyc'>

If bar is not a module or package, the second form will not work; a traceback is thrown instead:

>>> import os.walk as walk
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named walk

* In Python 3.6 and before, there was a bug with the initialization ordering of packages containing other modules, where in the loading stage of the package using import contained.module.something as alias in a submodule would fail where from contained.module import something as alias would not. See Imports in __init__.py and `import as` statement for a very illustrative example of that problem, as well as Python issues #23203 and #30024.

Why does importing a function from a module import the whole module?

There is no real mistery on "why" it is executed, python works this way.

The docs say:

The from form uses a slightly more complex process:

  1. find the module specified in the from clause, loading and initializing it if necessary;
  2. for each of the identifiers specified in the import clauses:

    1. check if the imported module has an attribute by that name
    2. if not, attempt to import a submodule with that name and then check the imported module again for that attribute
    3. if the attribute is not found, ImportError is raised.
    4. otherwise, a reference to that value is stored in the local namespace, using the name in the as clause if it is present, otherwise using the attribute name

And also (here the reference):

A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module name is encountered in an import statement. (They are also run if the file is executed as a script.)

This answer the question "why". Even if you load a single function from your module, the module is still initialized (makes sense to behave this way). Any "free" code hence is executed.

This means that you should not put "free" statements in a module unless they are meant to initialize it.

To prevent this behaviour, use the if __name__ == "main": statement as other answers said. Put inside this if all the code that should be executed only when the module is called directly (for example, code for testing purpose).

Using modules imported from another import

They are available in the following namespace:

import alt
print (alt.os.getcwd())

Python Import system, importing function from a module that imports the same function from another package

This is perfectly fine. The from x import name statement merely imports name from x – it does not care where name was initially defined.

In fact, the standard library itself frequently re-exports names from internal or C modules.

# collections/abc.py
from _collections_abc import *
from _collections_abc import __all__
from _collections_abc import _CallableGenericAlias

Re-exporting names can help make the public appearance of a package simpler to use, while giving complete freedom to how the implementation is structured.

However, one should be careful when re-exporting names across packages. Just because a package exposes a name today does not mean that a future version does so as well. When the intermediate package is not under your control, avoid making assumptions and prefer importing from the official source.

# bad: import undocumented attribute
from subprocess import os
# good: import with official name
import os

The notion of "where" an object was defined does not generally make sense. For example, consider defining a module for literal constants:

# constants.py
MIDNIGHT = 0
NOON = 12

There is a single value for every 0 and 12 throughout the entire application. The statement from constants import MIDNIGHT, NOON has no way of checking where the objects were defined initially.



Related Topics



Leave a reply



Submit