Import submodules all at once - python

I'm quite new at Python, but I'm experienced with other programming languages.
I have this line of code:
import module as m
If I try to access its functions:
m.spam.foo()
m.eggs.bar()
I get the following errors:
AttributeError: module 'module' has no attribute 'spam'
AttributeError: module 'module' has no attribute 'eggs'
On the other hand, if I write:
import module.spam, module.eggs
and then:
module.spam.foo()
module.eggs.bar()
It works properly.
Same if I write:
from module import spam, eggs
and:
spam.foo()
eggs.bar()
Works with no errors.
I prefer the first method since I don't have to manually import every single submodule before using it...
So, what's wrong with that method? Is there a workaround to make it work (I do not like the from module import * approach since they can be confused with my global variables)?
I searched everywhere inside the reference but could not find anything.

I don't know how well this solves your problem, because this code is actually longer than the from module import spam, eggs method, but this question might solve your problem. Basically, you would use an __init__ function to load all submodules.

Related

Does importing specific class from file instead of full file matters?

Most of the tutorials and books about Django or Flask import specific classes from files instead of importing the whole file.
For example, importing DataRequiered validator from wrtforms.validators is done via from wtforms import validators instead of importing it via import wtforms.validators as valids and then accessing DataRequiered with valids.DataRequiered.
My question is: Is there an reason for this ?
I thought to something like avoiding the loading a whole module for computation/memory optimization (is it really relevant?) ? Or is it simply to make the code more readable ?
My question is: Is there an reason for this ?
from module_or_package import something is the canonical pythonic idiom (when you only want to import something in your current namespace of course).
Also, import module_or_package.something only works if module_or_package is a package and something a submodule, it raises an ImportError(No module named something) if something is a function, class or whatever object defined in module_or_package, as can be seen in the stdlib with os.path (which is a submodule of the os.package) vs datetime.date (which is a class defined in the datetime module):
>>> import os.path as p
>>> p
<module 'posixpath' from '/home/bruno/.virtualenvs/blook/lib/python2.7/posixpath.pyc'>
vs
>>>import datetime.date as d
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named date
thought to something like avoiding the loading a whole module for computation/memory optimization (is it really relevant?)
Totally irrelevant - importing a given name from a module requires importing the whole module. Actually, this:
from module_or_package import something
is only syntactic sugar for
import module_or_package
something = module_or_package.something
del module_or_package
EDIT: You mention in a comment that
Right, but importing the whole module means loading it to the memory, which can be a reason for importing only a submodule/class
so it seems I failed to make the point clear: in Python, you can not "import only a submodule/class", period.
In Python, import, class and def are all executable statements (and actually just syntactic sugar for operation you can do 'manually' with functions and classes). Importing a module actually consists in executing all the code at the module's top-level (which will instanciate function and class objects) and create a module object (instance of module type) which attributes will be all names defined at the top-level via import, def and class statements or via explicit assignment. It's only when all this has been done that you can access any name defined in the module, and this is why, as I stated above,
from module import obj
is only syntactic sugar for
import module
obj = module.obj
del module
But (unless you do something stupid like defining a terabyte-huge dict or list in your module) this doesn't actually take that much time nor eat much ram, and a module is only effectively executed once per process the first time it's imported - then it's cached in sys.modules so subsequent imports only fetch it from cache.
Also, unless you actively prevents it, Python will cache the compiled version of the module (the .pyc files) and only recompile it if the .pyc is missing or older than the source .py file.
wrt/ packages and submodules, importing a submodule will also execute the package's __init__.py and build a module instance from it (IOW, at runtime, a package is also a module). Package initializer are canonically rather short, and actually quite often empty FWIW...
It depends, in the tutorial that was probably done for readability
Usually if you use most of the classes in a file, you import the file. If the files contains many classes but you only need a few, just import those.
It's both a matter of readability and optimization.

Why '__module__' class attribute can differ from actual module, where class was defined?

I'm trying to understand modules concept in python, therefore I'm trying to make some experiments to understand details more deeper :)
So, I see, that ndarray is defined in numpy.core.multiarray module initially. In my opinion, its __module__ attribute have to be numpy.core.multiarray, but actually it is numpy. Why does it happen?
I'm using Python 3 and numpy 1.14.3.
Code to reproduce is:
>>> import numpy
>>> numpy.ndarray.__module__
'numpy'
Thank you for your answers!

Why am I getting a no attribute error in my python script but not in my python interpreter? [duplicate]

There is one thing, that I do not understand.
Why does this
import scipy # happens with several other modules, too. I took scipy as an example now...
matrix = scipy.sparse.coo_matrix(some_params)
produce this error:
AttributeError: 'module' object has no attribute 'sparse'
This happens because the scipy module doesn't have any attribute named sparse. That attribute only gets defined when you import scipy.sparse.
Submodules don't automatically get imported when you just import scipy; you need to import them explicitly. The same holds for most packages, although a package can choose to import its own submodules if it wants to. (For example, if scipy/__init__.py included a statement import scipy.sparse, then the sparse submodule would be imported whenever you import scipy.)
Because you imported scipy, not sparse. Try from scipy import sparse?
AttributeError is raised when attribute of the object is not available.
An attribute reference is a primary followed by a period and a name:
attributeref ::= primary "." identifier
To return a list of valid attributes for that object, use dir(), e.g.:
dir(scipy)
So probably you need to do simply: import scipy.sparse
The default namespace in Python is "__main__". When you use import scipy, Python creates a separate namespace as your module name.
The rule in Pyhton is: when you want to call an attribute from another namespaces you have to use the fully qualified attribute name.

Why does this AttributeError in python occur?

There is one thing, that I do not understand.
Why does this
import scipy # happens with several other modules, too. I took scipy as an example now...
matrix = scipy.sparse.coo_matrix(some_params)
produce this error:
AttributeError: 'module' object has no attribute 'sparse'
This happens because the scipy module doesn't have any attribute named sparse. That attribute only gets defined when you import scipy.sparse.
Submodules don't automatically get imported when you just import scipy; you need to import them explicitly. The same holds for most packages, although a package can choose to import its own submodules if it wants to. (For example, if scipy/__init__.py included a statement import scipy.sparse, then the sparse submodule would be imported whenever you import scipy.)
Because you imported scipy, not sparse. Try from scipy import sparse?
AttributeError is raised when attribute of the object is not available.
An attribute reference is a primary followed by a period and a name:
attributeref ::= primary "." identifier
To return a list of valid attributes for that object, use dir(), e.g.:
dir(scipy)
So probably you need to do simply: import scipy.sparse
The default namespace in Python is "__main__". When you use import scipy, Python creates a separate namespace as your module name.
The rule in Pyhton is: when you want to call an attribute from another namespaces you have to use the fully qualified attribute name.

Problem with python and __import__

Sorry for the generic title, will change it once I understand the source of my problem
I have the following structure:
foo/
foo/__init__.py
foo/bar/
foo/bar/__init__.py
foo/bar/some_module.py
When I try to import some_module by doing so:
from foo.bar import some_module
it works like a charm.
But this is no good for me, since I only know the name of the module to import in runtime. so if I try:
from foo.bar import *
mod=__import__('some_module')
I get an error. Am I doing something wrong? Is there a better way to do this? and why is this happening?
Why is that? I am not quite sure I completely understand the concept behind python packages. I thought they were equivalent to java's packages and thus
I believe the proper way to do this is:
mod = __import__('foo.bar', fromlist = ['some_module'])
This way even the 'foo.bar' part can be changed at runtime.
As a result some_modulewill be available as mod.some_module; use getattr if you want it in a separate variable:
the_module = getattr(mod, 'some_module')
from foo.bar import *
is a bad practice since it imports some_module into the global scope.
You should be able to access your module through:
import foo.bar
mod = getattr(foo.bar, 'some_module')
It can be easily demonstrated that this approach works:
>>> import os.path
>>> getattr(os.path, 'basename')
<function basename at 0x00BBA468>
>>> getattr(os.path, 'basename\n')
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
getattr(os.path, 'basename\n')
AttributeError: 'module' object has no attribute 'basename
'
P.S. If you're still interested in using your kind of import statement. You need an eval:
from foo.bar import *
eval('some_module')
To clarify: not only it's bad practice to use *-import it's even worse in combination with eval. So just use getattr, it's designed exactly for situations like yours.
From the docs:
Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.
However, the dotted notation should work:
mod = __import__('foo.bar.some_module')

Categories