I have a python package that I'm writing and I'm having an issue where the standard library is being imported instead of my files because of name clashes.
For example, a file structure like below:
package/__init__.py
# No data in this file
#!/usr/bin/env python
print 'Loading module.py'
import signal
#!/usr/bin/env python
print 'Loading signal.py'
I get the following results when I run this:
$ ./module.py
Loading module.py
I would like to get:
$ ./module.py
Loading module.py
Loading signal.py
So, when I run module.py, it's import signal
goes to the stdlib version. How am I able to force module.py to import signal.py instead?
As noted in the tags, this needs to be able to run on python-2.4.3. While that is an old version, it's what is included in RHEL 5.
Just for a bit more information, I explicitly have the following setup:
[10:30pm][~/test] tree .
.
|-- package
| |-- __init__.py
| |-- module.py
| `-- signal.py
`-- script
[10:30pm][~/test] cat script
#!/usr/bin/env python
from package import signal
[10:30pm][~/test] cat package/__init__.py
[10:30pm][~/test] cat package/module.py
#!/usr/bin/env python
print "Loading module.py"
import signal
[10:30pm][~/test] cat package/signal.py
#!/usr/bin/env python
print "Loading signal.py"
[10:30pm][~/test] python ./script
Loading signal.py
[10:32pm][~/test] python ./package/module.py
Loading module.py
[10:32pm][~/test] python -m package.module
python: module package.module not found
Please note that when I ran ./package/module.py that the print statement in ./package/signal.py was not fired. This implies that the signal that was loaded is the one from the stdlib.
1 Answer. You can re-import a module in python, by using the importlib and its function reload.
In Python, you use the import keyword to make code in one module available in another. Imports in Python are important for structuring your code effectively. Using imports properly will make you more productive, allowing you to reuse code while keeping your projects maintainable.
What is Importing? Importing refers to allowing a Python file or a Python module to access the script from another Python file or module. You can only use functions and properties your program can access. For instance, if you want to use mathematical functionalities, you must import the math package first.
The problem in this case is that the built-in signal
module is imported as part of the interpreter's startup process. So by the time your code in module.py
runs, there is already an entry in sys.modules
under the name signal
, with the built-in module as its value. Since sys.modules
is the first place the import
statement looks, it's going to return that built-in module and stop there. It doesn't even bother to look for your own custom signal.py
.
I can think of three solutions:
import
statement will search directories in the order specified by sys.path
, and the current working directory when you run the interpreter is first on that list. signal
is sort of a special case because it gets imported automatically before your code runs, but there are a limited number of modules for which that is true, and those are the only ones you have to avoid name clashes with.del sys.modules['signal']
and replace the entry with your own custom signal
module. Don't actually do this unless your module is truly meant to be a drop-in replacement for the built-in signal
. If you do, then any code that runs import signal
from that point on will get your version, not the built-in one, and that could wreak havoc on any internal code that needs the signal
module to function.You can use the imp
module to get access to the internals of the import
function, or at least equivalent code, which will allow you to bypass the check of sys.modules
.
If you really do need to do this, here's a code sample you could use:
import imp, sys
f, path, desc = imp.find_module('signal', sys.path)
if f:
f.close()
signal = imp.new_module('signal')
execfile(path, signal.__dict__)
else:
raise ImportError('signal.py not found')
# signal is your module
This code snippet is roughly equivalent to import signal
except that it does not insert the module found into sys.modules
, and it does not look for builtin modules before searching the path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With