From ... Import or Import ... as for Modules

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

Python : 'import module' vs 'import module as'

The below syntax will help you in understanding the usage of using "as" keyword while importing modules

 import NAMES as RENAME from MODULE searching HOW

Using this helps developer to make use of user specific name for imported modules.
Example:

 import random 
print random.randint(1,100)

Now I would like to introduce user specific module name for random module thus
I can rewrite the above code as

 import random as myrand
print myrand.randint(1,100)

Now coming to your question; Which one is preferred?
The answer is your choice; There will be no performance impact on using "as" as part of importing modules.

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.

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.

Using modules imported from another import

They are available in the following namespace:

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

`from ... import` vs `import .`

It depends on how you want to access the import when you refer to it.

from urllib import request
# access request directly.
mine = request()

import urllib.request
# used as urllib.request
mine = urllib.request()

You can also alias things yourself when you import for simplicity or to avoid masking built ins:

from os import open as open_
# lets you use os.open without destroying the
# built in open() which returns file handles.

python import module from a package

Short answer

So what does the from packages import * really mean inside that __init__.py?

The __init__.py imports itself.

Explanation

You can only import modules, not packages. Packages are just containers for modules or sub-packages. When you "import" a package you actually import the module __init__.py.

The __init__.py with this content:

from packages import mod

imports the module mod into __init__.py. Therefore, it will be available
in your main.py via packages.mod (remember packages is represented by __init__.py).

When you change the content of __init__.py to:

from packages import *

You are importing the module __init__.py, the very same file you are in.
This works (a second import just triggers a lookup in sys.modules)
but won't give you the content of mod.

This means, you can use:

from module import *

but you cannot sensibly use this with an empty __init__.py:

from package import *

Because package is actually represented by the __init__.py and there
is nothing in it yet. You can check this (interactively or in file):

>>> import packages
>>> print(packages)
<module 'packages' from '/.../packages/__init__.py'>

In __init__.py you can write:

from packages.mod import *

and then in main.py:

print packages.hello()

works. Because the function hello() is now in the global name space of the
file __init__.py.

As mentioned in the answer by mozman, you can use __all__ in __init__.py to
list the modules that should be imported if from packages import * is used. This is designed for this case.

The __init__.py has only this content:

__all__ = ['mod']

Now you can do this in main.py:

from packages import *

print mod.hello()

If you extend your __init__.py:

__all__ = ['mod']

from packages import *

You can do this in main.py:

import packages

print packages.mod.hello()

But if you remove the from packages import * from __init__.py:

__all__ = ['mod'] 

You will get an error:

AttributeError: 'module' object has no attribute 'mod'

because the __all__ is only used for the from packages import * case.
Now we are back to the __init__.py imports itself.

Importing modules from parent folder

It seems that the problem is not related to the module being in a parent directory or anything like that.

You need to add the directory that contains ptdraft to PYTHONPATH

You said that import nib worked with you, that probably means that you added ptdraft itself (not its parent) to PYTHONPATH.

Can't import my own modules in Python

In your particular case it looks like you're trying to import SomeObject from the myapp.py and TestCase.py scripts. From myapp.py, do

import SomeObject

since it is in the same folder. For TestCase.py, do

from ..myapp import SomeObject

However, this will work only if you are importing TestCase from the package. If you want to directly run python TestCase.py, you would have to mess with your path. This can be done within Python:

import sys
sys.path.append("..")
from myapp import SomeObject

though that is generally not recommended.

In general, if you want other people to use your Python package, you should use distutils to create a setup script. That way, anyone can install your package easily using a command like python setup.py install and it will be available everywhere on their machine. If you're serious about the package, you could even add it to the Python Package Index, PyPI.



Related Topics



Leave a reply



Submit