Can anyone help me howto import a module class? - python

I have a module example.py with the follow class:
class add:
def __init__(self, x, y):
self.x= x
self.y= y
def adding_two_nbr(self):
return self.x*self.y
when I import the module as the following i got error:
import example
obj = example.add(1,2)
obj.adding_two_nbr()
error:
AttributeError: 'add' object has no attribute 'adding_two_nbr'

The code works for me smoothly. Change the second block of code as
import example
obj = example.add(1,2)
print(obj.adding_two_nbr())
Save this file as import_file.py in the same directory as example.py and run import_file.py.

I think add class is already defined in python module so you need to change to another name
AttributeError: 'add' object has no attribute 'adding_two_nbr'
adding_two_nbr not defined in python add module.

Related

module "twitter" has no attribute "Twitter"

I have the following file, twitter.py, which defines a class called Twitter:
class Twitter:
data = {}
def __init__(self):
pass
def tweet(self):
print("I'm tweeting")
And I have another file, main.py, in the same directory as twitter.py which imports twitter and attempts to instantiate the class:
import twitter
twitterObj = twitter.Twitter()
Unfortunately, Python throws the error message: AttributeError: module 'twitter' has no attribute 'Twitter'
What am I doing wrong?
Can't reproduce this error on my machine. I'm assuming you have a module with the name "twitter" installed to your python path that is overriding the project file. Try renaming twitter.py.

Importing Python class by string

I'm trying to instantiate a class in a submodule using a string name. I've been trying to follow this SO question unsuccessfully:
Python dynamic instantiation from string name of a class in dynamically imported module
I've created the following directory structure:
__init__.py
mymodule/
├── __init__.py
└── MyClass.py
MyClass.py contains:
class MyClass():
def __init__(self, someparam):
print(someparam)
From python I try the following which produces an error.
getattr(importlib.import_module('mymodule'), 'MyClass')
AttributeError: 'module' object has no attribute 'MyClass'
I've tried most of the other solutions put forth in the referenced question and not gotten any of them to work with this setup.
Here other failed attempts based on answers I've tried to follow to illustrate what I've tried and failed at:
import importlib
module = importlib.import_module('mymodule')
class_ = getattr(module, 'MyClass')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'MyClass'
Your code is equivalent to:
from mymodule import MyClass
mymodule doesn't contain MyClass, so you will get an error. You want the equivalent of:
from mymodule.myclass import MyClass
That would be:
getattr(importlib.import_module('mymodule.MyClass'), 'MyClass')

Instantiate class dynamically with locate

I am trying to instantiate a class dynamically from a string that is fed to a method.
from pydoc import locate
name = "folder.subfolder.classname"
my_class = locate(name)
instance = my_class()
Doing this results in an error:
TypeError: 'module' object is not callable
My question is: how can I dinamically know which class I need to call? If I hardcode the value and do my_class.classname() I can instantiate it, but I want that last part to be dynamic, instead of hardcoded. How can I do that?
Edit 2:
This solution will gather all classes available in the module the user provides, and then simply instantiates the first class.
import inspect
from pydoc import locate
name = "folder.subfolder.classname"
my_module = locate(name)
all_classes = inspect.getmembers(my_module, inspect.isclass)
if len(all_classes) > 0:
instance = all_classes[0][1]()
Edit:
Gathered from the comments I believe the following code will work for your use case:
from pydoc import locate
name = "folder.subfolder.classname"
my_module = locate(name)
class_name = name.rsplit('.')[-1]
my_class = getattr(my_module, class_name)
instance = my_class()
You do seem to be a bit confused as to what modules are which resulted in our miscommunication. class.py doesn't point to a class, but to a module. In that module (your class.py file) there can be multiple classes. For the answer above I just assume that in your class.py file you have a class with the same name as the file.
Original Answer:
Well as your error shows, your my_class variable is actually a module object. The name you provide doesn't actually point to your class but to the module containing the class.
To get a class from a module object by string you can do:
my_class = getattr(module, class_name)
and then like in your example code you can instantiate it like this:
instance = my_class()
To bring it all together:
module_name = "folder.subfolder.module_name"
my_module = locate(module_name)
my_class = getattr(my_module, class_name)
instance = my_class()
You didn't locate the class inside of the file:
from pydoc import locate
name = "folder.subfolder.filename.classname"
my_class = locate(name)
instance = my_class()

Importing a module with imp

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()

Dynamic Importing in Python (Dotted statments)

I'm having trouble with the following code:
def get_module(mod_path):
mod_list = mod_path.split('.')
mod = __import__(mod_list.pop(0))
while mod_list:
mod = getattr(mod, mod_list.pop(0))
return mod
When I do get_module('qmbpmn.common.db_parsers') I get the error message:
AttributeError: 'module' object has no attribute 'db_parsers'.
However: import qmbpmn.common.db_parsers works perfectly fine.
When using __import__ to import submodules, you must pass the parent package as the fromlist argument:
>>> __import__("os.path")
<module 'os' from '/usr/lib/python2.6/os.pyc'>
>>> __import__("os.path", fromlist=["os"])
<module 'posixpath' from '/usr/lib/python2.6/posixpath.pyc'>
__import__ works with the dotted module path, so this should work
def get_module(mod_path):
return __import__(mod_path)
or more simply
get_module = __import__
Perhaps I am misunderstanding the problem
importing a package does not automatically import all the submodules into it's namespace. For example
import qmbpmn
does not mean that
qmbpmn.common.db_parsers
will automatically resolve

Categories

Resources