Python __import__ is only giving me top level module [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'm doing
module = __import__("client.elements.gui.button", globals(), locals(), [], 0)
But it's only returning client.
What is my problem?

That's what __import__ does.
When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name.
You're not really supposed to use __import__; if you want to import a module dynamically, use importlib.import_module.

Accepted answer is correct, but if you read on in the docs you'll find that this can be gotten around with an admittedly unsettling "hack" by using __import__ like so:
module = __import__('client.elements.gui.button', fromlist=[''])
It doesn't really matter what you pass in for fromlist so long as it's a non-empty list. This signals to the default __import__ implementation that you want to do a from x.y.z import foo style import, and it will return the the module you're after.
As stated you should use importlib instead, but this is still a workaround if you need to support Python versions < 2.7.

It only obtains the top level, but you can also work around this like so:
module_name = 'some.module.import.class'
module = __import__(module_name)
for n in module_name.split('.')[1:]:
module = getattr(module, n)
# module is now equal to what would normally
# have been retrieved where you to properly import the file

Related

how to import list from other module in python if module name starts with a number [duplicate]

Basically there is a file called 8puzzle.py and I want to import the file into another file (in the same folder and I cannot change the file name as the file is provided). Is there anyway to do this in Python? I tried usual way from 8puzzle import *, it gives me an error.
Error is:
>>> import 8puzzle
File "<input>", line 1
import 8puzzle
^
SyntaxError: invalid syntax
>>>
You could do
puzzle = __import__('8puzzle')
Very interesting problem. I'll remember not to name anything with a number.
If you'd like to import * -- you should check out this question and answer.
The above answers are correct, but as for now, the recommended way is to use import_module function:
importlib.import_module(name, package=None)
Import a module. The name
argument specifies what module to import in absolute or relative terms
(e.g. either pkg.mod or ..mod). If the name is specified in relative
terms, then the package argument must be set to the name of the
package which is to act as the anchor for resolving the package name
(e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).
The import_module() function acts as a simplifying wrapper around
importlib.__import__(). This means all semantics of the function are
derived from importlib.__import__(). The most important difference
between these two functions is that import_module() returns the
specified package or module (e.g. pkg.mod), while __import__() returns
the top-level package or module (e.g. pkg).
If you are dynamically importing a module that was created since the
interpreter began execution (e.g., created a Python source file), you
may need to call invalidate_caches() in order for the new module to be
noticed by the import system.
__import__ is not recommended now.
importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
An implementation of the built-in __import__() function.
Note Programmatic importing of modules should use import_module() instead of this function.
The file directory structure is as follows:
daily
-- 20210504
permutations.py
__init__.py
__init__.py
You can import the permutations module by __import__ or importlib.import_module.
The official documentation recommends using importlib.import_module.
import(name, globals=None, locals=None, fromlist=(), level=0) -> module
Import a module. Because this function is meant for use by the Python interpreter and not for general use, it is better to
useimportlib.import_module()to programmatically import a module.
What is the difference?
If implemented using __import__.
For example:
res = __import__('daily.20210504.permutations')
The result of res is the daily module.
So, if you want to get the permutations module, you need to provide the fromlist parameter, which is written as follows.
res = __import__('daily.20210504.permutations', fromlist=('daily.20210504'))
The result of res can be seen now as
That's the right result.
What if I use importlib.import_module?
res = importlib.import_module('daily.20210504.permutations')
this allows you to get the permutations module directly.
Don't use the .py extension in your imports.
Does from 8puzzle import * work?
For what it's worth, from x import * is not a preferred Python pattern, as it bleeds that module's namespace into your current context.
In general, try to import things you specifically want from that module. Any global from the other module can be imported.
e.g., if you have 8puzzle.foo you could do `from 8puzzle import
Edit:
While my .py message is correct, it isn't sufficient.
The other poster's __import__('8puzzle') suggestion is correct. However, I highly recommend avoiding this pattern.
For one, it's reserved an internal, private Python method. You are basically breaking the fundamental assumptions of what it means to be able to import a module. Simply renaming the file to something else, like puzzle8, will remedy this.
This will frustrate the hell out of experienced Python programmers who are expecting to know what your imports are at the top and are expecting code to (try to) conform to PEP8.

How can avoid loading particular variable from module in python [duplicate]

This question already has answers here:
Does Python have “private” variables in classes?
(15 answers)
Closed 7 years ago.
(I've checked out Does Python have “private” variables in classes? -- it asks about classes rather than modules. As such, answers there don't cover import which is what I'm interested in.)
Consider, there is a module called X with variable y. If any other module tries to import the module X, how to avoid loading the variable y in Python?
For example:
# x.py
y=10
We then use this in some other module:
import x
print x.y
How to avoid accessing x.y from the module x.py ?
If you do import module, there's no way to hide any global members, and that's intentional: the module object returned is the "true" one, the very same that's used by the module's members. Dirty hacks like __getattr__ are also prohibited for modules.
One way is to mark "internal" entities with a leading underscore to hint the user they are not intended for external use. This isn't necessary for references to other modules imported by yours since the guidelines explicitly discourage external use of them (the only exception is if the referenced module is inaccessible the normal way).
When doing from module import *, however, you don't get a module reference but import things from it directly into the current namespace. By default, everything except names starting from an underscore is imported. You can override this by defining the __all__ module attribute.
In normal use import foo only imports the module once; all other imports see that it has been imported, and doesn't load it again.
Quoth https://docs.python.org/3/reference/import.html#the-module-cache:
During import, the module name is looked up in sys.modules and if
present, the associated value is the module satisfying the import, and
the process completes. However, if the value is None, then an
ImportError is raised. If the module name is missing, Python will
continue searching for the module.
This has been long been a feature of the interpreter going back at least to version 2.7 and probably earlier.
Speaking to your specific question, there is no variable y, there is x.y because that's what you imported. If you do the highly unrecommended from module import * you can end up with a y, but you shouldn't do that.

import vs __import__( ) vs importlib.import_module( )?

I noticed Flask was using Werkzeug to __import__ a module, and I was a little confused. I went and checked out the docs on it and saw that it seems to give you more control somehow in terms of where it looks for the module, but I'm not sure exactly how and I have zero idea how it's different from importlib.import_module.
The odd thing in the Werkzeug example is that it just says __import__(import_name), so I don't see how that's any different from just using the import statement, since it's ignoring the optional extra parameters.
Can anyone explain? I looked at other people having asked similar questions on SO previously but they weren't very clearly phrased questions and the answers didn't address this at all.
__import__ is a low-level hook function that's used to import modules; it can be used to import a module dynamically by giving the module name to import as a variable, something the import statement won't let you do.
importlib.import_module() is a wrapper around that hook* to produce a nice API for the functionality; it is a very recent addition to Python 2, and has been more fleshed out in Python 3. Codebases that use __import__ generally do so because they want to remain compatible with older Python 2 releases, e.g. anything before Python 2.7.
One side-effect of using __import__ can be that it returns the imported module and doesn't add anything to the namespace; you can import with it without having then to delete the new name if you didn't want that new name; using import somename will add somename to your namespace, but __import__('somename') instead returns the imported module, which you can then ignore. Werkzeug uses the hook for that reason in one location.
All other uses are to do with dynamic imports. Werkzeug supports Python 2.6 still so cannot use importlib.
* importlib is a Pure-Python implementation, and import_module() will use that implementation, whist __import__ will use a C-optimised version. Both versions call back to importlib._bootstrap._find_and_load() so the difference is mostly academic.
__import__(import_name), so I don't see how that's any different from
just using the import statement
Both __import__() and importlib.import_module() allow you to import a module when you have the module name as a string. You cannot write:
x = 're'
import x
or you'll get:
File "1.py", line 3, in <module>
import x ImportError: No module named x

dynamic execute a function by a string like 'module.function' [duplicate]

This question already has answers here:
Python function pointer
(8 answers)
Closed 9 years ago.
if I have a string like 'module.function', How can I execute function just by one step?
likesomefunction('os.error','args')
You can dynamically get the modules using sys.modules and then you can use getattr to get the attributes from the module, like this
import sys
func = "os.error"
module, function = func.split(".", 1)
getattr(sys.modules[module], function)()
sys.modules can give only the modules which are already loaded. So, if you want to load a module dynamically you can use __import__ function like this
For example,
module, function = "math.factorial".split(".", 1)
print getattr(__import__(module), function)(5)
Output
120
All you need to do is
from module import function
and you'll be able to call
function(x, y, z)
in your code.

In python, how to import filename starts with a number

Basically there is a file called 8puzzle.py and I want to import the file into another file (in the same folder and I cannot change the file name as the file is provided). Is there anyway to do this in Python? I tried usual way from 8puzzle import *, it gives me an error.
Error is:
>>> import 8puzzle
File "<input>", line 1
import 8puzzle
^
SyntaxError: invalid syntax
>>>
You could do
puzzle = __import__('8puzzle')
Very interesting problem. I'll remember not to name anything with a number.
If you'd like to import * -- you should check out this question and answer.
The above answers are correct, but as for now, the recommended way is to use import_module function:
importlib.import_module(name, package=None)
Import a module. The name
argument specifies what module to import in absolute or relative terms
(e.g. either pkg.mod or ..mod). If the name is specified in relative
terms, then the package argument must be set to the name of the
package which is to act as the anchor for resolving the package name
(e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).
The import_module() function acts as a simplifying wrapper around
importlib.__import__(). This means all semantics of the function are
derived from importlib.__import__(). The most important difference
between these two functions is that import_module() returns the
specified package or module (e.g. pkg.mod), while __import__() returns
the top-level package or module (e.g. pkg).
If you are dynamically importing a module that was created since the
interpreter began execution (e.g., created a Python source file), you
may need to call invalidate_caches() in order for the new module to be
noticed by the import system.
__import__ is not recommended now.
importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
An implementation of the built-in __import__() function.
Note Programmatic importing of modules should use import_module() instead of this function.
The file directory structure is as follows:
daily
-- 20210504
permutations.py
__init__.py
__init__.py
You can import the permutations module by __import__ or importlib.import_module.
The official documentation recommends using importlib.import_module.
import(name, globals=None, locals=None, fromlist=(), level=0) -> module
Import a module. Because this function is meant for use by the Python interpreter and not for general use, it is better to
useimportlib.import_module()to programmatically import a module.
What is the difference?
If implemented using __import__.
For example:
res = __import__('daily.20210504.permutations')
The result of res is the daily module.
So, if you want to get the permutations module, you need to provide the fromlist parameter, which is written as follows.
res = __import__('daily.20210504.permutations', fromlist=('daily.20210504'))
The result of res can be seen now as
That's the right result.
What if I use importlib.import_module?
res = importlib.import_module('daily.20210504.permutations')
this allows you to get the permutations module directly.
Don't use the .py extension in your imports.
Does from 8puzzle import * work?
For what it's worth, from x import * is not a preferred Python pattern, as it bleeds that module's namespace into your current context.
In general, try to import things you specifically want from that module. Any global from the other module can be imported.
e.g., if you have 8puzzle.foo you could do `from 8puzzle import
Edit:
While my .py message is correct, it isn't sufficient.
The other poster's __import__('8puzzle') suggestion is correct. However, I highly recommend avoiding this pattern.
For one, it's reserved an internal, private Python method. You are basically breaking the fundamental assumptions of what it means to be able to import a module. Simply renaming the file to something else, like puzzle8, will remedy this.
This will frustrate the hell out of experienced Python programmers who are expecting to know what your imports are at the top and are expecting code to (try to) conform to PEP8.

Categories

Resources