Importing a submodule given a module object - python

I am given a module as an object, and I need to import a submodule from it. Like this:
import logging
x = logging
Now I want to import logging.handlers using only x and not the name "logging". (This is because I am doing some dynamic imports and won't know the name of the module.)
How do I do this? If I do import x.handlers it fails.

Try:
__import__('%s.handlers' % x.__name__)
Note that this will return a reference to logging, which you probably won't care about. It will create x.handlers though.

You can use built-in function __import__:
http://docs.python.org/library/functions.html#import

Related

Define alias for Python module within that module

Is there a way to define an alias for a module within that module itself and is it a good idea to do so?
For example, if we have a module some_looooooooong_name and would like to allow users to use slm as an alias such that even if they just import it as
import some_looooooooong_name
They can still use slm.name. Is that possible and OK to do?
use as :)
import some_looooooooong_name as module
from some_looooooooong_name import function_with_long_name as func
print(name.do_something())
print(func())

Python: How to import all methods and attributes from a module dynamically

I'd like to load a module dynamically, given its string name (from an environment variable). I'm using Python 2.7. I know I can do something like:
import os, importlib
my_module = importlib.import_module(os.environ.get('SETTINGS_MODULE'))
This is roughly equivalent to
import my_settings
(where SETTINGS_MODULE = 'my_settings'). The problem is, I need something equivalent to
from my_settings import *
since I'd like to be able to access all methods and variables in the module. I've tried
import os, importlib
my_module = importlib.import_module(os.environ.get('SETTINGS_MODULE'))
from my_module import *
but I get a bunch of errors doing that. Is there a way to import all methods and attributes of a module dynamically in Python 2.7?
If you have your module object, you can mimic the logic import * uses as follows:
module_dict = my_module.__dict__
try:
to_import = my_module.__all__
except AttributeError:
to_import = [name for name in module_dict if not name.startswith('_')]
globals().update({name: module_dict[name] for name in to_import})
However, this is almost certainly a really bad idea. You will unceremoniously stomp on any existing variables with the same names. This is bad enough when you do from blah import * normally, but when you do it dynamically there is even more uncertainty about what names might collide. You are better off just importing my_module and then accessing what you need from it using regular attribute access (e.g., my_module.someAttr), or getattr if you need to access its attributes dynamically.
Not answering precisely the question as worded, but if you wish to have a file as proxy to a dynamic module, you can use the ability to define __getattr__ on the module level.
import importlib
import os
module_name = os.environ.get('CONFIG_MODULE', 'configs.config_local')
mod = importlib.import_module(module_name)
def __getattr__(name):
return getattr(mod, name)
My case was a bit different - wanted to dynamically import the constants.py names in each gameX.__init__.py module (see below), cause statically importing those would leave them in sys.modules forever (see: this excerpt from Beazley I picked from this related question).
Here is my folder structure:
game/
__init__.py
game1/
__init__.py
constants.py
...
game2/
__init__.py
constants.py
...
Each gameX.__init__.py exports an init() method - so I had initially a from .constants import * in all those gameX.__init__.py which I tried to move inside the init() method.
My first attempt in the lines of:
## -275,2 +274,6 ## def init():
# called instead of 'reload'
+ yak = {}
+ yak.update(locals())
+ from .constants import * # fails here
+ yak = {x: y for x,y in locals() if x not in yak}
+ globals().update(yak)
brec.ModReader.recHeader = RecordHeader
Failed with the rather cryptic:
SyntaxError: import * is not allowed in function 'init' because it contains a nested function with free variables
I can assure you there are no nested functions in there. Anyway I hacked and slashed and ended up with:
def init():
# ...
from .. import dynamic_import_hack
dynamic_import_hack(__name__)
Where in game.__init__.py:
def dynamic_import_hack(package_name):
print __name__ # game.init
print package_name # game.gameX.init
import importlib
constants = importlib.import_module('.constants', package=package_name)
import sys
for k in dir(constants):
if k.startswith('_'): continue
setattr(sys.modules[package_name], k, getattr(constants, k))
(for setattr see How can I add attributes to a module at run time? while for getattr How can I import a python module function dynamically? - I prefer to use those than directly access the __dict__)
This works and it's more general than the approach in the accepted answer cause it allows you to have the hack in one place and use it from whatever module. However I am not really sure it's the best way to implement it - was going to ask a question but as it would be a duplicate of this one I am posting it as an answer and hope to get some feedback. My questions would be:
why this "SyntaxError: import * is not allowed in function 'init'" while there are no nested functions ?
dir has a lot of warnings in its doc - in particular it attempts to produce the most relevant, rather than complete, information - this complete worries me a bit
is there no builtin way to do an import * ? even in python 3 ?

Most pythonic way to import all objects in a module as their name in the module

When you import a module, python protects the namespace by importing all objects in that module as module.objectname instead of objectname. import module.objectname as objectname will import the object as its original name in the module, but writing out every object in this manner would be tedious for a large module. What is the most pythonic way to import all objects in a module as their name within the module?
This would import everything from modules as their name:
from module import *
But it's not really good practice. Import only what is really needed and use PEP8 tests for your code.
You only need to use this form
import module.objectname as objectname
If you wish to alias the objectname to a different name
Usually you say
from module import objectname, objectname2, objectname3
There is no "Pythonic" way to import all the objects as from module import * is discouraged (causes fragile code) so can hardly be called Pythonic

Python - How can you use a module's alias to import its submodules?

I have a long module name and I want to avoid having to type it all over many times in my document. I can simply do import long_ass_module_name as lamn and call it that way. However, this module has many submodules that I wish to import and use as well.
In this case I won't be able to write import lamn.sub_module_1 because python import does not recognize this alias I made for my long_ass_module_name. How can I achieve this?
Should I simply automatically import all submodules in my main module's __init__.py?
An aliased object still changes when you import submodules,
import my_long_module_name as mlmn
import my_long_module_name.submodule
mlmn.submodule.function()
The import statement always takes the full name of the module. The module is just an object, and importing a submodule will add an attribute to that object.
This (highly unrecommendable) way of importing all the members of an object to the current namespace works by looking up the vars() dictionary:
import my_bad_ass_long_module.bafd as b
# get __dict__ of current namespace
myn = vars()
for k,v in vars(b).items():
# populate this namespace with the all the members of the b namespace (overwriting!)
myn[k] = v

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