Is there a difference between following import styles in python? [duplicate] - python

Should I use
from foo import bar
OR
import foo.bar as bar
when importing a module and and there is no need/wish for changing the name (bar)?
Are there any differences? Does it matter?

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.

This is a late answer, arising from what is the difference between 'import a.b as b' and 'from a import b' in python
This question has been flagged as a duplicate, but there is an important difference between the two mechanisms that has not been addressed by others.
from foo import bar imports any object called bar from namespace foo into the current namespace.
import foo.bar as bar imports an importable object (package/module/namespace) called foo.bar and gives it the alias bar.
What's the difference?
Take a directory (package) called foo which has an __init__.py containing:
# foo.__init__.py
class myclass:
def __init__(self, var):
self.__var = var
def __str__(self):
return str(self.__var)
bar = myclass(42)
Meanwhile, there is also a module in foo called bar.py.
from foo import bar
print(bar)
Gives:
42
Whereas:
import foo.bar as bar
print(bar)
Gives:
<module 'foo.bar' from '/Users//..../foo/bar.py'>
So it can be seen that import foo.bar as bar is safer.

Both are technically different:
import torch.nn as nn will only import a module/package torch.nn, wheres
from torch import nn can and will prefer to import an attribute .nn from the torch module/package. Importing a module/package torch.nn is a fall.back.
In practice, it is bad style to have the same fully qualified name refer to two separate things. As such, torch.nn should only refer to a module/package. In this common case, both import statements are functionally equivalent: The same object is imported and bound to the same name.
Which one to choose comes down to preference if the target always is a module. There are practical differences when refactoring:
import torch.nn as nn guarantees .nn is a module/package. It protects against accidentally shadowing with an attribute.
from torch import nn does not care what .nn is. It allows to transparently change the implementation.
7.11. The import statement
The basic import statement (no from clause) is executed in two steps:
find a module, loading and initializing it if necessary
define a name or names in the local namespace for the
scope where the import statement occurs.
[...]
The from form uses a slightly more complex process:
find the module specified in the from clause, loading and initializing it if necessary;
for each of the identifiers specified in the import clauses:
check if the imported module has an attribute by that name
if not, attempt to import a submodule with that name and then check the imported module again for that attribute

You can use as to rename modules suppose you have two apps that have views and you want to import them
from app1 import views as views1
from app2 import views as views2
if you want multiple import use comma separation
>>> from datetime import date as d, time as t
>>> d
<type 'datetime.date'>
>>> t
<type 'datetime.time'>

The only thing I can see for the second option is that you will need as many lines as things you want to import. For example :
import foo.bar as bar
import foo.tar as tar
import foo.zar as zar
Instead of simply doing :
from foo import bar, tar, zar

The difference between import module and from module import is mainly subjective. Pick the one you like best and be consistent in your use of it. Here are some advantage of both to help you decide.
advantage of import
Less maintenance of your import statements.
Don't need to add any additional imports to start using another item from the module
advantage of from torch import nn
Less typing to use the nn
More control over which items of a module can be accessed

Related

package imports libraries without even intializing class

The doubt is the if import a class from a package inside another package like this :
from bar import foo
Does it initialize the class? and if the module has an import at the first line like :
import tensorflow
class foo:
def __init__(self):
# some things
Does it import the package even if we don't initialize the class from another file?
Does it initialize the class?
No, it just gives your program access to that class - ready to be instantiated to an object when you want to (then it will call the __init__ method).
Does it import the package even if we don't initialize the class from another file?
Yes. You can see this as if you were to just import bar, then you would be able to access the imported tensorflow module with bar.tensorflow, i.e. it is actually imported even if there is nothing else in the module.
In your specific case of just importing foo from bar, we can still access tensorflow via the inspect built-in package that will give us a reference to bar and thus .tensorflow from foo.
import inspect
from bar import foo
print(inspect.getmodule(foo).itertools) #<module 'itertools' (built-in)>
I'm not sure if there is an easier way to "get at" bar from foo without using inspect, but this is what I found for the purpose of explaining your case fully!

Custom Py Module: Intra Module Importing

I am creating a custom Python module that I wanted to work similarly to something like numpy where most of the functionality can be accessed by calling np.function() or what have you. However, in creating my submodules and __init__.py file, I think that I've run into a circular import reference. Here's what I'm trying to do and the error I'm seeing, any tips to help me get this working the way I envisioned are greatly appreciated:
Let's call the module "foobar" and say I have a folder named "foobar" on the path and in this folder are three py files: "__init__.py", "foo.py", and "bar.py".
An example of submodule 1, "foo.py":
import bar
class Foo():
def __init__(self):
pass
def runfunc(self):
bar.func()
An example of submodule 2, "bar.py":
import foo
def func():
f=foo.F()
An example of __init__.py:
import numpy
from foo import *
from bar import *
__all__ = ['foo', 'bar']
So what I perceive to be my issue is that when foo is imported, it imports bar, which imports foo, which creates a loop (in my mind). I am also confused as to the use of __init__.py if, when it is called and imports other modules they cannot see each other when executing (i.e. I need to import bar into foo even though __init__.py did this).
When I run something from a script trying to import the entire module, I get the error in bar.py "ImportError: cannot import name foo". I am actually also having this issue elsewhere in the same module where I have a file with the base class "Base" and the extended class "Extended" where base.py needs to import extended.py so it can spawn instances of the expanded class and extended.py needs to import base.py so it can inherit the class.
Thanks for any help in advance!

Imports behave differently when in __init__.py that is imported

Imports in an __init__.py seem to behave differently when the file is run, to when it is imported.
If we have the following files:
run.py:
import test
test/b.py:
class B(object):
pass
test/__init__.py:
from b import B
print B
print b
If we run __init__.py we get an error as I expect:
% python test/__init__.py
<class 'b.B'>
Traceback (most recent call last):
File "test/__init__.py", line 6, in <module>
print b
NameError: name 'b' is not defined
But if we run.py then we don't:
% python run.py
<class 'test.b.B'>
<module 'test.b' from '~/temp/test/b.py'>
I would expect the behaviour to be the same. Why does this work?
This only works if we do it in an __init__.py. If we:
mv __init__.py a.py
touch __init__.py
and make run.py:
import test.a
Then we do get the error.
The situation is the following: you have a script (run.py), a package test and its submodule test.b.
Whenever you import a submodule in Python, the name of that submodule is automatically stored into the parent package. So that when you do import collections.abc (or from collections.abc import Iterable, or similar), the package collections automatically gets the attribute abc.
This is what's happening here. When you do:
from b import B
the name b is automatically loaded into test, because b is a submodule of the test package.
Even if you don't do import b explicitly, whenever you import that module, the name is placed into test. Because b is a submodule of test, and it belongs to test.
Side node: your code won't work with Python 3, because relative imports have been removed. To make your code work with Python 3, you would have to write:
from test.b import B
This syntax is perfectly identical to from b import B, but is much more explicit, and should help you understand what's going on.
Reference: the Python reference documentation also explains this behavior, and includes a helpful example, very similar to this situation (the difference is just that an absolute import is used, instead of a relative import).
When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in __import__()) a binding is placed in the parent module's namespace to the submodule object. For example, if package spam has a submodule foo, after importing spam.foo, spam will have an attribute foo which is bound to the submodule.
Let's say you have the following directory structure:
spam/
__init__.py
foo.py
bar.py
and spam/__init__.py has the following lines in it:
from .foo import Foo
from .bar import Bar
then executing the following puts a name binding to foo and bar in the spam module:
>>> import spam
>>> spam.foo
<module 'spam.foo' from '/tmp/imports/spam/foo.py'>
>>> spam.bar
<module 'spam.bar' from '/tmp/imports/spam/bar.py'>
Given Python's familiar name binding rules this might seem surprising, but it's actually a fundamental feature of the import system. The invariant holding is that if you have sys.modules['spam'] and sys.modules['spam.foo'] (as you would after the above import), the latter must appear as the foo attribute of the former.

How do I make classes from a submodule available in a parent module's namespace?

Here's a python module. foo is in sys.path.
foo\
__init__.py
bar\
__init__.py
base.py
class Base(object)
derived.py
import foo.bar.base as base
class Derived(base.Base)
I've got nothing fancy going on yet. If I want to instantiate the Derived class from the derived module, I can do that easily enough:
import foo.bar.derived as derived
print(derived.Derived())
However, I'd like to just import the bar module and call bar.Derived(), because I plan to have lots of classes within lots of different modules, and I don't want to deal with all these tentacular import paths. My understanding is that I can simply import Derived into the namespace of the bar module, by modifying my project like so:
foo\
__init__.py
bar\
__init__.py
from foo.bar.derived import Derived
base.py
class Base(object)
derived.py
import foo.bar.base as base
class Derived(base.Base)
Now I should be able to do the following:
import foo.bar as bar
print(bar.Derived())
But I get an AttributeError complaining that the foo module has no submodule called bar:
test.py (1): import foo.bar
foo\bar\__init__.py (1): from foo.bar.derived import Derived
foo\bar\derived.py (1): import foo.bar.base as base
AttributeError: 'module' object has no attribute 'bar'
In fact, my original test code (at top) doesn't work either! As soon as I try to import foo.bar, I get errors.
What I can gleam from this error is that the import statement in __init__.py causes derived.py to be executed before bar is fully loaded, and therefore it can't import the module (also from bar) which contains its own base class. I'm coming from the C++ world, where ultra-nested namespaces aren't as integral and a simple forward declaration would negate this problem, but I've been led to believe that what I'm looking for is possible and at least a somewhat acceptably Pythonic solution. What am I doing wrong? What's the correct way to make classes from a submodule available in the parent module's namespace?
If you're working with Python 2.5 or later, try using explicit relative imports (http://www.python.org/dev/peps/pep-0328/#guido-s-decision):
test.py (1): import foo.bar
foo\bar\__init__.py (1): from .derived import Derived
foo\bar\derived.py (1): from . import base
(Note that if you are indeed working with Python 2.5 or 2.6, you'll need to include from __future__ import absolute_import in your modules.)
in derived.py, use this:
EDIT: as JAB pointed out, implicit relative imports are deprecated, to the following isn't recommended (although it does work still in Python 2.7 - with no deprecation errors!).
import base # this is all you need - it's in the current directory
Instead, use:
from . import base #
(or)
from foo.bar import base
instead of:
import foo.bar.base as base
This will solve both your errors (since they're from the same issue). Your import doesn't work since there is no base function or class inside the foo.bar.base module.

How does import keyword in python actually work?

Let's say I have 3 files:
a.py
from d import d
class a:
def type(self):
return "a"
def test(self):
try:
x = b()
except:
print "EXCEPT IN A"
from b import b
x = b()
return x.type()
b.py
import sys
class b:
def __init__(self):
if "a" not in sys.modules:
print "Importing a!"
from a import a
pass
def type(self):
return "b"
def test(self):
for modules in sys.modules:
print modules
x = a()
return x.type()
c.py
from b import b
import sys
x = b()
print x.test()
and run python c.py
Python comes back complaining:
NameError: global name 'a' is not
defined
But, a IS in sys.modules:
copy_reg
sre_compile
locale
_sre
functools
encodings
site
__builtin__
operator
__main__
types
encodings.encodings
abc
errno
encodings.codecs
sre_constants
re
_abcoll
ntpath
_codecs
nt
_warnings
genericpath
stat
zipimport
encodings.__builtin__
warnings
UserDict
encodings.cp1252
sys
a
codecs
os.path
_functools
_locale
b
d
signal
linecache
encodings.aliases
exceptions
sre_parse
os
And I can alter b.py such that:
x = a()
changes to
x = sys.modules["a"].a()
And python will happily run that.
A couple questions arise from this:
Why does python say it doesn't know what a is, when it is in sys.modules?
Is using sys.modules a "proper" way to access class and function definitions?
What is the "right" way to import modules?
ie
from module import x
or
import module
I guess it's a problem of scoping, if you import a module in your constructor you can only use it in your constructor, after the import statement.
According to the Python documentation,
Import statements are executed in two steps: (1) find a module, and initialize it if necessary; (2) define a name or names in the local namespace (of the scope where the import statement occurs).
So the problem is that even though module a has been imported, the name a has only been bound in the scope of the b.__init__ method, not the entire scope of b.py. So in the b.test method, there is no such name a, and so you get a NameError.
You might want to read this article on importing Python modules, as it helps to explain best practices for working with imports.
In your case, a is in sys.modules.. but not everything in sys.modules is in b's scope. If you want to use re, you'd have to import that as well.
Conditional importing is occasionally acceptable, but this isn't one of those occasions. For one thing, the circular dependency between a and b in this case is unfortunate, and should be avoided (lots of patterns for doing so in Fowler's Refactoring).. That said, there's no need to conditionally import here.
b ought to simply import a. What were you trying to avoid by not importing it directly at the top of the file?
It is bad style to conditionally import code modules based on program logic. A name should always mean the same thing everywhere in your code. Think about how confusing this would be to debug:
if (something)
from office import desk
else
from home import desk
... somewhere later in the code...
desk()
Even if you don't have scoping issues (which you most likely will have), it's still confusing.
Put all your import statements at the top of your file. That's where other coders will look for them.
As far as whether to use "from foo import bar" verses just "import foo", the tradeoff is more typing (having to type "foo.bar()" or just type "bar()") verses clearness and specificity. If you want your code to be really readable and unambiguous, just say "import foo" and fully specify the call everywhere. Remember, it's much harder to read code than it is to write it.

Categories