importing module elements in another with no qualified name - python

My problem is quite easy but I can not find a good answer because the search engines are ambiguous on the term "module".
What I want do to is roughly this :
Module : a.py
x = 2
Module : b.py
import a
Now, I want to be able to access x from b without using qualified name (i.e. without typing a.x, just with x). In my situation I cannot use :
from a import x
because I don't know which elements a will contains. I can not use
from a import *
neither. Is there any simple way to merge or join the modules (I mean the Object Modules) ?

This is not a good idea, but you can use:
globals().update(vars(a))
to add all names defined in the a module to your local namespace. This is almost the same as from a import *. To emulate from a import * exactly, without using from a import * itself, you'd have to use:
globals().update(p for p in vars(a).items() if p[0] in getattr(a, '__all__', dir(a)))
You normally just would use x = a.x or from a import x.
If you are using zipimport you don't have to do any of this. Just add the path to the archive to your sys.path:
import sys
sys.path.insert(0, '/path/to/archive.zip')
from test import x

Related

Abbreviation for long python import path

Given imports like this:
from a.very.long.list.of.packages.aaa.bbb.ccc import abc
from a.very.long.list.of.packages.ddd.eee import de
from a.very.long.list.of.packages.fff import f
from a.very.long.list.of.packages import somepackage
is there any way to define aliases for the common part of the module path and reuse it?
I'm imagining something like this:
x = a.very.long.list.of.packages
from x.aaa.bbb.ccc import abc
from x.ddd.eee import de
from x.fff import f
from x import somepackage
Given x = a.very.long.list.of.packages, Python will try to resolve all the attributes and fail immediately because no name a has been defined. If it already exists, it's unlikely that it has the attribute very and the object this attribute points to has the attribute long and so on. Anyway, everything to the right of the assignment operator will be evaluated to some object, and it's not possible to import stuff from objects with from ... import ....
You can use dynamic importing with the built-in importlib module. It lets you treat strings as paths to modules.

How to use from x import y using importlib in Python

I wanted to install and import a package from script. Then I wanted to add from x import y and from x import * in that script.(I was making some functions actually).
I successfully installed and imported using subprocess and importlib. But I'm at a loss in from x import y and from x import *. Tried these codes and some others.
globals()[package] = importlib.import_module('package','class')
globals()[package] = importlib.import_module('class','package')
globals()[package] = importlib.import_module('package','*')
globals()[package] = importlib.import_module('*','package')
importlib.import_module('gtts','gTTS')
importlib.import_module('gtts','*')
But they didn't work. Shows:
NameError: name 'gTTS' is not defined
ModuleNotFoundError: No module named 'gTTS'
etc.
I don't think you can load methods directly, since this method just loads modules. A module is loaded with import module and i defined as "A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. " (check documentation). from x import y does also do the import module but sets another namespace (see discussion here). What you can do is load your module and then set your namespace manually afterwards, this is what the from x import y syntax does. You can load a module with the path (in this example i want to load read_csv from pandas):
importlib.import_module(".io.parsers", "pandas")
(check the path with print(inspect.getmodule(read_csv).__name__))
Also a solution like jottbe mentioned in the commentary would be possible
The exact syntax to correspond to mischva11's answer, is as follows:
tempmod = importlib.import_module("x_mymodule")
y = x_mymodule.y
del tempmod # optionally delete the reference to the parent module
Imports only the attribute y from the module x_mymod, similar to from x_mymodule import y. You can get the ... as z functionality by assigning it to any name you want in the 2nd line of code.
I found it useful to delete the parent module from the namespace, when using this in a sub-module, to prevent cluttering up the namespace.
I think to get the import * function you'll have to iterate through the module's attributes and assign them to a named attribute. Here are two hints that help you get there:
How to list all functions in a Python module?
Set attributes of module from inside the module: https://stackoverflow.com/a/2933481/2453202

Import * from module by importing via string

I know I can use importlib to import modules via a string. How can I recreate the import * functionality using this library? Basically, I want something like this:
importlib.import_module('path.to.module', '*')
My reasons for not name-spacing the imported attributes are deliberate.
Here is a solution: import the module, then one by one make alias in the current namespace:
import importlib
# Import the module
mod = importlib.import_module('collections')
# Determine a list of names to copy to the current name space
names = getattr(mod, '__all__', [n for n in dir(mod) if not n.startswith('_')])
# Copy those names into the current name space
g = globals()
for name in names:
g[name] = getattr(mod, name)
Here is shorten version for #HaiVu answer which refers to this solution from #Bakuriu
import importlib
# import the module
mod = importlib.import_module('collections')
# make the variable global
globals().update(mod.__dict__)
Note:
This will import lots of things beside the user-defined variables
#HaiVu solution did the best of it ie. only import user-defined variables

python import all modules to a python file which we can import in another file?

i'm new to python. i've some python scripts where in need to import different python modules.
Is it possible to
import all modules to one single file, say modules.py
and import this modules.py to all scripts, so that no need to import modules to each script ?
Thanks in advance
In mymodules:
import module1
import module2
in app:
from mymodules import *
But is it really worth it? The Zen of python states:
Explicit is better than implicit.
Copying some lines at the top of a file isn't really too much trouble.
There are at least 4 Ways to Import a Module:
import X, imports the module X: this way you can use X.whatever to refer to things defined in module X.
from X import *, imports the module X: this way you can simply use a plain name to refer to things defined in module X.
from X import x, y, z: you can now use x and y and z in the current name space.
X = __import__(‘X’) works like import X but this time the module name is a string. Use it it you don't know the module name before execution.
Think about namespace as a Python dictionary structure, where the dictionary keys represent the names and the dictionary values the object itself. Using import you can name the module inside your namespace.
That's said, you can perfectly import the modules inside a script (name it importer os something), and then import "importer" and everything will be inside your namespace.
Is that a good idea?, probably no because is common to found the same name (method, function or whatever) inside different modules and if that happens then ambiguity appears.

Dynamic import in Python

How can I make this import:
from module import *
with imp module?
Disclaimer:
I need use imp module because I need make several statements and I want to do it dynamicly
I need use * because I need that in the file I made the import, the variables and methods defined in module be available directly, i mean without module.method or module.variable. And I want import all variables and methods in the module because I don't know what methods or variables can be in the module in the future
Here!
def load_everything_from(module_names):
g = globals()
for module_name in module_names:
m = __import__(module_name)
names = getattr(m, '__all__', None)
if names is None:
names = [name for name in dir(m) if not name.startswith('_')]
for name in names:
g[name] = getattr(m, name)
I am kind of making things up there a little bit with trying to find an __all__ symbol first and then, if that files, doing a dir() and grabbing symbols that look non-private — you would have to look at the implementation of import * to know if that resembles Python's actual logic closely enough for your purposes.
If you are using django (as mentionned in comments), something like this should work
from django.utils import importlib
my_module = importlib.import_module('app.my_module')
from my_module import *
But I agree that it may be dangerous
You can do it by:
from imp import *
but remember:
Explicit is better than implicit.
(from The Zen of Python - read it by using the following command: import this)

Categories