Python Module and Class - AttributeError: module has no attribute - python

I'm new to python and I'm trying to create a module and class.
If I try to import mystuff and then use cfcpiano = mystuff.Piano(), I get an error:
AttributeError: module 'mystuff' has no attribute 'Piano'
If I try from mystuff import Piano I get:
ImportError: cannot import name 'Piano'
Can someone explain what is going on? How do I use a module and class in Python
mystuff.py
def printhello():
print ("hello")
def timesfour(input):
print (input * 4)
class Piano:
def __init__(self):
self.type = raw_input("What type of piano? ")
def printdetails(self):
print (self.type, "piano, " + self.age)
Test.py
import mystuff
from mystuff import Piano
cfcpiano = mystuff.Piano()
cfcpiano.printdetails()

If you want to create a python module named mystuff
Create a folder with name mystuff
Create an __init__.py file
#__init__.py
from mystuff import Piano #import the class from file mystuff
from mystuff import timesfour,printhello #Import the methods
Copy your class mystuff.py to the folder mystuff
Create file test.py outside the folder(module) mystuff.
#test.py
from mystuff import Piano
cfcpiano = Piano()
cfcpiano.printdetails()

Related

Python dynamically import classes an call their functions

I have one Abstract Animal class.
from abc import ABC, abstractmethod
class Animal(ABC): # Inherit from ABC(Abstract base class)
#abstractmethod # Decorator to define an abstract method
def feed(self):
pass
And three classes which Implements it
from Animal import Animal
class Lion(Animal):
def feed(self):
print("Feeding a lion with raw meat!")
from Animal import Animal
class Panda(Animal):
def feed(self):
print("Feeding a panda with some tasty bamboo!")
from Animal import Animal
class Snake(Animal):
def feed(self):
print("Feeding a snake with mice!")
Now I just want to import all classes, which are in the project folder and call the feed function of all classes, when there is a feed function.
from glob import glob
import os
if __name__ == '__main__':
for file in glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), "*.py")):
name = os.path.splitext(os.path.basename(file))[0]
# add package prefix to name, if required
module = __import__(name)
try:
module.feed()
except Exception as e:
print(e)
My Problem is now, that I get the errors:
module 'Animal' has no attribute 'feed'
module 'Lion' has no attribute 'feed'
module 'main' has no attribute 'feed'
module 'Panda' has no attribute 'feed'
module 'Snake' has no attribute 'feed'
Can someone help me with this?
I take it your files are called Snake.py, Panda.py etc. If so then you are invoking feed() on the files not the classes. You need to get the modules (which you've done), then get the class and then call the method:
from glob import glob
import os
if __name__ == '__main__':
for file in glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), "*.py")):
name = os.path.splitext(os.path.basename(file))[0]
if name == "Animal" or name == "main": # avoid main.py and Animal.py
continue
# add package prefix to name, if required
module = __import__(name)
try:
# get the class
cls = getattr(module, name)
# instantiate the class and call the method
cls().feed()
except Exception as e:
print(e)
Ive also included a safety check to exclude main.py and Animal.py

Relative imports do not work from imported modules

I have a program that is laid out like the following:
test\test.py
test\modules\base.py
test\modules\blah.py
I need to load modules by name. Each module implements a class with the same methods, so I load them into a dictionary so that I can reference them as needed. I'm getting the follow error trying to do a relative import.
File "modules/blah.py", line 1, in <module>
from .base import BaseModule
ImportError: attempted relative import with no known parent package
Is there a way to use relative imports from code imported using importlib?
I'm using Python 3. The following is a simple example showing this error...
test\test.py:
#!/usr/bin/env python
import importlib
class Test():
def __init__(self):
spec = importlib.util.spec_from_file_location("blah", "modules/blah.py")
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
def main():
t = Test()
if __name__ == '__main__':
main()
test\modules\base.py:
class BaseModule():
modulename = "base"
def __init__(self,name):
print("Initializing module %s" % (self.modulename))
test\modules\blah.py:
from .base import BaseModule
class BlahModule(BaseModule):
modulename = "blah"
Adding the following code should help:
import os
import sys
module_path = "modules/blah.py"
module_dir = os.path.dirname(module_path)
if module_dir not in sys.path:
sys.path.append(module_dir)
# do actual import of module here

Define an object as 'root' of module

I have a module module.py
class SomeClass():
def __init__(self):
self.var='123'
def printit(self):
print self.var
And now I'm trying to import this module into script.py and call the method printit from the class SomeClass
import module
module.SomeClass().printit()
I also can do it by another way:
from module import SomeClass
SomeClass().printit()
And another one:
from module import SomeClass as module
module().printit()
It's nice but i want to get something like this:
import module
module().printit()
or even
import module
SomeClass().printit()
Generally I want to make a module that will export SomeClass by default. Is it possible to make something like this by changing module.py?

How do I properly reference Python classes?

I'm working on writing my first Python class. Being the java programmer that I am, I have something like this:
#class1.py
class class1:
def __init__(self):
#Do stuff here
And in my current script:
import class1
object = class1()
I'm getting a Name Error: name 'class1' is not defined
I've also tried this, with no luck:
import class1
object = class1.class1()
The error I get here is AttributeError: 'module' object has no attribute 'class1'
What am I doing wrong?
Python import is by module and then by the contents of the module, so for your class1.py it becomes:
from class1 import class1
Python module docs
In Python you import the modules. For class1.py file you can use:
from class1 import class1
Or if you have more than one....
from class1 import *

Class is not defined despite being imported

I seem to have run into a really confusing error. Despite importing the .py file containing my class, Python is insistent that the class doesn't actually exist.
Class definition in testmodule.py:
class Greeter:
def __init__(self, arg1=None):
self.text = arg1
def say_hi(self):
return self.text
main.py:
#!/usr/bin/python
import testmodule
sayinghi = Greeter("hello world!")
print(sayinghi.say_hi())
I have a theory that the import is not working as it should. How do I do this correctly?
Use the fully-qualified name:
sayinghi = testmodule.Greeter("hello world!")
There is an alternative form of import that would bring Greeter into your namespace:
from testmodule import Greeter
import testmodule
# change to
from testmodule import Greeter
or
import testmodule
sayinghi = Greeter("hello world!")
# change to
import testmodule
sayinghi = testmodule.Greeter("hello world!")
You imported the module/package, but you need to reference the class inside it.
You could also do this instead
from testmodule import *
but then beware of namespace pollution

Categories

Resources