Importing a module with imp - python

I have a script that does the following:
import imp
imp.load_source("storage_configuration_reader","/bi/opt/RNAspace/rnaspace_sources/rnaspace/rnaspace/rnaspace/dao/storage_configuration_reader.py")
Later on, I call a class of the this module with the same name:
config = storage_configuration_reader()
If I import it like the above I get the following NameError NameError: global name 'storage_configuration_reader' is not defined but if I use the following code:
import imp
imp.load_source("storage_configuration_reader","/bi/opt/RNAspace/rnaspace_sources/rnaspace/rnaspace/rnaspace/dao/storage_configuration_reader.py")
import storage_configuration_reader
config = storage_configuration_reader()
Then I get this error TypeError: 'module' object is not callable
Changing the name of the imp.load_source doesn't help to import the object:
import imp
imp.load_source("storage_configuration","/bi/opt/RNAspace/rnaspace_sources/rnaspace/rnaspace/rnaspace/dao/storage_configuration_reader.py")
<module 'storage_configuration' from '/bi/opt/RNAspace/rnaspace_sources/rnaspace/rnaspace/rnaspace/dao/storage_configuration_reader.pyc'>
import storage_configuration
config = storage_configuration_reader()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'storage_configuration_reader' is not defined
Which is the best way (AKA working way) to import an object like this?
Info: The storage_configuration_reader definition:
class storage_configuration_reader(object):
"""
Class configuration_reader: this object read the config file and return the
different configuration values
"""
...

imp.load_source loads the module using the given path and name it using the new name, it's not like from your_module_at_path import your_class_by_name, it's just like import your_module_at_path as new_name (not exactly the same).
Besides, you need to assign the name to a variable to use it:
wtf=imp.load_source("new_module_name", your_path)
#wtf is the name you could use directly:
config = wtf.storage_configuration_reader()
the name new_module_name is stored as a key in dictionary sys.modules, you can use it like this:
sys.modules['new_module_name'].storage_configuration_reader()
A simpler way to import a module from some other directory is adding the module's path to sys.path:
import sys
sys.path.append("/bi/opt/RNAspace/rnaspace_sources/rnaspace/rnaspace/rnaspace/dao")
import storage_configuration_reader
config = storage_configuration_reader.storage_configuration_reader()

Related

How to import a module from sub directory

I failed to import a module from sub directory in python. Below is my project structure.
./main.py
./sub
./sub/__init__.py
./sub/aname.py
when I run python main.py, I got this error:
Traceback (most recent call last):
File "main.py", line 4, in <module>
import sub.aname
File "/Users/dev/python/demo/sub/__init__.py", line 1, in <module>
from aname import print_func
ModuleNotFoundError: No module named 'aname'
I don't know it failed to load the module aname. Below is the source code:
main.py:
#!/usr/bin/python
import sub.aname
print_func('zz')
sub/__init__.py:
from aname import print_func
sub/aname.py:
def print_func( par ):
print ("Hello : ", par)
return
I am using python 3.6.0 on MacOS
There are several mistakes in your Python scripts.
Relative import
First, to do relative import, you must use a leading dots (see Guido's Decision about Relative Imports syntax).
In sub/__init__.py, replace:
from aname import print_func
with:
from .aname import print_func
Importing a function
To import a function from a given module you can use the from ... import ... statement.
In main.py, replace:
import sub.aname
with:
from sub import print_func
from sub import aname
aname.print_func('zz')
Probably the most elegant solution is to use relative imports in your submodule sub:
sub.__init__.py
from .aname import print_func
But you also need to import the print_func in main.py otherwise you'll get a NameError when you try to execute print_func:
main.py
from sub import print_func # or: from sub.aname import print_func
print_func('zz')

Module has no attribute error in python3

contents of io.py
class IO:
def __init__(self):
self.ParsingFile = '../list'
def Parser(self):
f = open(ParsingFile, 'r')
print(f.read())
contents of main.py
import sys
sys.path.insert(0, "lib/")
try:
import io
except Exception:
print("Could not import one or more libraries.")
exit(1)
print("Libraries imported")
_io_ = io.IO()
When I run python3 main.py I get the following error:
Libraries imported
Traceback (most recent call last):
File "main.py", line 11, in <module>
_io_ = io.IO()
AttributeError: module 'io' has no attribute 'IO'
Any idea what's going wrong?
My file was called io. It seems that there already exists a package called io which caused the confusion.
Your package name (io) conflicts with the Python library's package with the same name, so you actually import a system package.
You can check this by printing io.__all__.
Changing io.py to something else is probably the best way to go to avoid similar problems. Otherwise, you can use an absolute path.
try
from io import IO
That worked for me when trying to import classes from another file
this has more information:
Python module import - why are components only available when explicitly imported?

Importing code from a dynamically created module in Python

I have a project that tries to create a new module dynamically and then in a subsequent exec statement tries to import that module.
import imp
s="""
class MyClass(object):
def __init__(self):
pass
def foo(self):
pass
"""
mod = imp.new_module("testmodule.testA")
exec s in mod.__dict__
exec "import testmodule.testA"
But this throws this exception:
Traceback (most recent call last):
File "test.py", line 14, in <module>
exec "import testmodule.testA"
File "<string>", line 1, in <module>
ImportError: No module named testmodule.testA
I've tried several things: adding it to sys.modules, creating a scope dict containing the name and the module as well. But no dice. I can see testmodule.testA when I do a print locals() in my exec statement, but I can't import it. What am I missing here?
Thank you.
You'll need to add your module to the sys.modules structure for import to find it:
import sys
sys.modules['testmodule.testA'] = mod
You already have the module object however and there is not much point in importing it again. mod is a reference to what Python would otherwise 'import' already.
The following would work without an import call:
mod.MyClass
If you need the module in an exec call, add it to the namespace there:
exec 'instance = MyClass()' in {'MyClass': mod.MyClass}

error when using import command in python

I'm new to python and now learning how to to import a module or a function, but I got these posted errors. The python code is saved under the name: hello_module.py
python code:
def hello_func():
print ("Hello, World!")
hello_func()
import hello_module
hello_module.hello_func()
error message:
Traceback (most recent call last):
File "C:/Python33/hello_module.py", line 9, in <module>
import hello_module
File "C:/Python33\hello_module.py", line 10, in <module>
hello_module.hello_func()
AttributeError: 'module' object has no attribute 'hello_func'
You cannot and should not import your own module. You defined hello_func in the current namespace, just use that directly.
You can put the function in a separate file, then import that:
File foo.py:
def def hello_func():
print ("Hello, World!")
File bar.py:
import foo
foo.hello_func()
and run bar.py as a script.
If you try to import your own module, it'll import itself again, and when you do that you import an incomplete module. It won't have it's attributes set yet, so hello_module.hello_func doesn't yet exist, and that breaks.

Writing and importing custom modules/classes

I've got a class that I'm trying to write called dbObject and I'm trying to import it from a script in a different folder. My structure is as follows:
/var/www/html/py/testobj.py
/var/www/html/py/obj/dbObject.py
/var/www/html/py/obj/__init__.py
Now, __init__.py is an empty file. Here are the contents of dbObject.py:
class dbObject:
def __init__():
print "Constructor?"
def test():
print "Testing"
And here's the contents of testobj.py:
#!/usr/bin/python
import sys
sys.path.append("/var/www/html/py")
import obj.dbObject
db = dbObject()
When I run this, I get:
Traceback (most recent call last):
File "testobj.py", line 7, in <module>
db = dbObject()
NameError: name 'dbObject' is not defined
I'm new to Python, so I'm very confused as to what I'm doing wrong. Could someone please point me in the right direction?
EDIT: Thanks to Martijn Pieters' answer I modified my testobj.py as follows:
#!/usr/bin/python
import sys
sys.path.append("/var/www/html/py")
sys.path.append("/var/www/html/py/dev")
from obj.dbObject import dbObject
db = dbObject()
However, now when I run it I get this error:
Traceback (most recent call last):
File "testobj.py", line 7, in <module>
db = dbObject()
TypeError: __init__() takes no arguments (1 given)
Is this referring to my init.py or the constructor within dbObject?
EDIT(2): Solved that one myself, the constructor must be able to take at least one parameter - a reference to itself. Simple fix. Looks like this problem is solved!
EDIT (Final): This is nice - I can cut out the import sys and sys.path.append lines and it still works in this instance. Lovely.
You need to import the class from the module:
from obj.dbObject import dbObject
This adds the class dbObject directly to your local namespace.
Your statement import obj.dbObject adds the name obj to the local namespace, so you could also do this instead:
db = obj.dbObject.dbObject()
because obj.dbObject is the dbObject.py module in your obj package directory.

Categories

Resources