Import modules using a variable in Python [duplicate] - python

This question already has answers here:
How can I import a module dynamically given its name as string?
(10 answers)
Closed 9 years ago.
I have a script which imports modules on-the-fly. Because modules name are changed as soon as a new version appears, it is difficult to check if the specific module name is also changed in the script. Because of this, I keep the modules name in the top of the script, in variables, like in this example:
var1 = 'moduleName1_v04'
var2 = 'moduleName2_v08'
...................
import var1
...................
import var2
...................
But if I am writing like this, I will get an error.
The question is: how to import a module using a variable like in the example? Is it possible?

Yes, you can achieve this quite easily by using importlib.import_module:
import importlib
module = importlib.import_module(var1)
Alternatively, you can use the __import__() built-in function
>>> sys = __import__("sys")
>>> sys
<module 'sys' (built-in)>
The __import__() function is the function that the interpreter uses to import modules. However, it's discouraged to use or modify this in favor of the simpler, safer import hooks, such as the first one i mentioned above. Quoting the important docs:
This function is invoked by the import statement. It can be replaced
(by importing the builtins module and assigning to
builtins.__import__) in order to change semantics of the import
statement, but doing so is strongly discouraged as it is usually
simpler to use import hooks (see PEP 302) to attain the same goals and
does not cause issues with code which assumes the default import
implementation is in use. Direct use of __import__() is also
discouraged in favor of importlib.import_module().
Hope this helps!

Yes, you can.
For example, using importlib.import_module:
>>> var1 = 'sys'
>>> import importlib
>>> mod = importlib.import_module(var1)
>>> mod
<module 'sys' (built-in)>

Related

Restore np.array after accidentally assigning to it [duplicate]

How do I reimport a module? I want to reimport a module after making changes to its .py file.
For Python 3.4+:
import importlib
importlib.reload(nameOfModule)
For Python < 3.4:
reload(my.module)
From the Python docs
Reload a previously imported module. The argument must be a module object, so it must have been successfully imported before. This is useful if you have edited the module source file using an external editor and want to try out the new version without leaving the Python interpreter.
Don't forget the caveats of using this method:
When a module is reloaded, its dictionary (containing the module’s global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem, but if the new version of a module does not define a name that was defined by the old version, the old definition is not removed.
If a module imports objects from another module using from ... import ..., calling reload() for the other module does not redefine the objects imported from it — one way around this is to re-execute the from statement, another is to use import and qualified names (module.*name*) instead.
If a module instantiates instances of a class, reloading the module that defines the class does not affect the method definitions of the instances — they continue to use the old class definition. The same is true for derived classes.
In python 3, reload is no longer a built in function.
If you are using python 3.4+ you should use reload from the importlib library instead:
import importlib
importlib.reload(some_module)
If you are using python 3.2 or 3.3 you should:
import imp
imp.reload(module)
instead. See http://docs.python.org/3.0/library/imp.html#imp.reload
If you are using ipython, definitely consider using the autoreload extension:
%load_ext autoreload
%autoreload 2
Actually, in Python 3 the module imp is marked as DEPRECATED. Well, at least that's true for 3.4.
Instead the reload function from the importlib module should be used:
https://docs.python.org/3/library/importlib.html#importlib.reload
But be aware that this library had some API-changes with the last two minor versions.
If you want to import a specific function or class from a module, you can do this:
import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function
Another small point: If you used the import some_module as sm syntax, then you have to re-load the module with its aliased name (sm in this example):
>>> import some_module as sm
...
>>> import importlib
>>> importlib.reload(some_module) # raises "NameError: name 'some_module' is not defined"
>>> importlib.reload(sm) # works
Although the provided answers do work for a specific module, they won't reload submodules, as noted in This answer:
If a module imports objects from another module using from ... import ..., calling reload() for the other module does not redefine the objects imported from it — one way around this is to re-execute the from statement, another is to use import and qualified names (module.*name*) instead.
However, if using the __all__ variable to define the public API, it is possible to automatically reload all publicly available modules:
# Python >= 3.5
import importlib
import types
def walk_reload(module: types.ModuleType) -> None:
if hasattr(module, "__all__"):
for submodule_name in module.__all__:
walk_reload(getattr(module, submodule_name))
importlib.reload(module)
walk_reload(my_module)
The caveats noted in the previous answer are still valid though. Notably, modifying a submodule that is not part of the public API as described by the __all__ variable won't be affected by a reload using this function. Similarly, removing an element of a submodule won't be reflected by a reload.
import sys
del sys.modules['module_name']
import module_name

Python import via exec does not work, while hardcoded import works

Inside a function, I have to import a variable (dict) from a module dynamically:
exec("from ctrl_%s import default_settings" % get_version_id(iid))
which doesnt work. When referencing this variable later, it says: UnboundLocalError: local variable 'default_settings' referenced before assignment
The variable is in the global scope of the module to import.
But:
This all works, if I hardcode this statement without exec(). The string is correctly formed, I can print it out.
Someone knows what to do?
I highly would discourage to use exec in the first place, it often does not do what you want especially if some special syntax is involved like here.
But fortunately there are some tricks:
e.g. you can import the module and use the dict or getattr:
import math
getattr(math,"sin")
math.__dict__['sin']
Edit just checked my answer and I saw you wanted to import a module ...
But there is also a trick for this:
https://docs.python.org/3/library/functions.html#__import__
Look also at this question for some examples:
How to import a module given its name as string?

How do I export a single function as a module in Python? [duplicate]

This question already has answers here:
Callable modules
(7 answers)
Closed 3 years ago.
I'm writing a module called foo that has many internal functions, but ultimately boils down to a single external function foo(). When using this module/function, I'd like to do
import foo
foo(whatever)
instead of
from foo import foo
foo(whatever)
Is this possible?
You could monkey patch the sys.modules dictionary to make the name of your module point to the function instead of your module.
foo.py (the file defining your module foo) would look like this
import sys
def foo(x):
return x + x
sys.modules[__name__] = foo
then you can use this module from a different file like this
import foo
print(foo(3))
6
There are probably reasons for why you shouldn't do this. sys.modules isn't supposed to point to functions, when you do from some_module import some_function, the module some_module is what gets added to sys.modules, not the function some_function.
It is not strictly possible. Python module names are ment to help the programmer distinguish between modules. So even if you had one function, bar in your module foo, using import foo will still need a foo.bar(). You're probably better off just using from foo import *.
However there may be a way around this. Python also has built-in functions, and you may be able to add your own functions to this. Doing so might require rewriting the compile though.
So conclusion: writing from foo import * isn't all that ugly and is a lot easier and prettier than the long way around.

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)

__builtin__ module in Python

If I have a module Test and if I need to list all the functions in them, I do this:
import Test
dir(Test)
Unless I import the module I won't be able to use the functions defined in them.
But all the functions in __builtin__ module can be used without importing. But without import __builtin__ I am not able to do a dir(__builtin__). Does that mean we use the functions without importing the entire module?
from __builtin__ import zip
Is it something like the above? But if I do del zip, I get
NameError: name 'zip' is not defined
Can anyone please explain this behavior?
As explained in the Python language docs, names in Python are resolved by first looking them up in the local scope, then in any enclosing local scope, then in the module-level scope and finally in the namespace of the built-ins. So built-ins are somehow special-cased. They are not imported in your module's scope, but if a name is not found anywhere else, Python will look it up in the scope __builtin__.
Note that you can access the contents of this scope without importing it. A portable way to do this is
import sys
print(dir(sys.modules["__builtin__"]))
In CPython, this also works
print(dir(__builtins__))
but this is considered an implementation detail and might not be available for other Python implementations or future versions.
I'm by no means knowledgeable about python, but maybe dir(__builtins__), with an "s", is what you're after?
Works for me on plain Python 3.1.
when python interpreter start, it will by default execute something like
from __builtin__ import *
which allows you to use all the functions/attributes defined inside __builtin__ module
However to use __builtin__ symbol itself, you need to do
import __builtin__
this is how import statement syntax works.

Categories