Python: class not callable from separate file? - python

I have a class, robot, in a file called robot.py
I want to create a robot instance in my main script like so:
in robot.py:
class robot(object):
def __init__(self,pygame,screen_width,screen_height):
in main.py:
import pygame, sys, copy
import mouse
import robot
import menu
import button
from pygame.locals import *
...
size = [1200,900]
my_robot = robot(pygame,size[0]-400,size[1]-100)
error:
me:cup-robot Me$ python run.py
Traceback (most recent call last):
File "run.py", line 24, in <module>
my_robot = robot(pygame,size[0]-400,size[1]-100)
TypeError: 'module' object is not callable
how do I do this?

Two choices :
import robot and then prefix all with robot :
my_robot = robot.robot(pygame,size[0]-400,size[1]-100)
or
from robot import robot and then your code should work. But then, you can see that you won't be able to distinguish if robot is a module or the class, so you should not name the class and the file with the same name.

Change your import statement:
from robot import robot
You have robot defined both as a module (robot.py) as well as a class. You need to import the class from the module so it is publicly available.

Related

Why do I receive an AttributeError even though import, spelling and file location is correct?

I am using PyCharm
All files are in the directory 'venv'
venv
NoteFunction.py
NoteMainApp.py
...
I split up my code in five separate files. One 'main' file, gathering all other files and creating eventually the GUI. The prefix for the files is 'Note' followed an appropriate description.
My problem now is the import of 'NoteTopMenu' into the main file 'NoteMainApp'.
The code is:
import NoteStatusbar as SB
import NoteTopMenu as TM
import NoteWidgets as NW
import tkinter as tk
class MainApp(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self,parent)
super().__init__(parent)
self.topbar = TM.TopMenu(parent)
self.widget = NW.FrontFrames(parent)
self.statusbar = SB.StatusBar(parent)
root = tk.Tk()
MainApp(root).pack(side="top", fill="both")
root.mainloop()
I receive the error message:
Traceback (most recent call last):
File "C:/Users/PycharmProjects/MindNotez/NoteMainApp.py", line 2, in <module>
import NoteTopMenu as TM
File "C:\Users\PycharmProjects\MindNotez\NoteTopMenu.py", line 2, in <module>
import NoteMainApp as Main
File "C:\Users\PycharmProjects\MindNotez\NoteMainApp.py", line 29, in <module>
MainApp(root).pack(side="top", fill="both")
File "C:\Users\PycharmProjects\MindNotez\NoteMainApp.py", line 13, in __init__
self.topbar = TM.TopMenu(parent)
AttributeError: module 'NoteTopMenu' has no attribute 'TopMenu'
The code in NoteTopMenu is:
import NoteMainApp as Main
import NoteWidgets as NW
import tkinter as tk
class TopMenu(NW.FrontFrames):
"""Class creating the top menu bar."""
def __init__(self, master):
super().__init__(master)
# *******Top-Navigation Bar (tnb)**********
tnb = tk.Menu(master)
Main.root.config(menu=tnb)
....
If I comment the NoteTopMenu out in the main file, the code runs without a problem. I checked my spelling but PyCharm also offers me code-completion. Therefore, PyCharm finds the file, the module, my class and other module are imported without an issue. Do you know why the file/module is not being found or fails to be imported?
Full code is here on GitHub: MindNotez
Thank you very much for your help!
You invoke NoteMainApp.py which imports NoteTopMenu.py which imports NoteMainApp.py which does not go on to re-import NoteTopMenu.py (because the import has already started). The import of NoteMainApp.py then goes on to parse the rest of the file. At this point the module NoteTopMenu is defined, but it doesn't have any attributes (because you haven't got round to defining them yet) ... hence the error.
I suggest that NoteTopMenu.py should not import NoteMainApp.py (and if there are any bits which both files need, they should be moved into another file that both can import)

How to solve this Python import circular reference

I have a class JCheq, with a static var named 'logger'.
JCheq imports module printing_systems, but I need to use JCheq.logger from printing_systems.
My code does not compile after I put import JCheq in printing_systems.py.
jcheq.py
from printing_systems import printing_systems
from logger import logger
class JCheq:
logger = logger.Logger('logs/jcheq.log', loglevel=logger.Logger.INFO)
def __init__(self):
pass
...
printing_systems/printing_systems.py
from jcheq import JCheq
class WinLPR:
def __init__(self):
pass
#staticmethod
def send(spool, params):
temp_dir = tempfile.mkdtemp()
try:
JCheq.logger.log('Creando archivo temporal en dir: ' + temp_dir, logger.Logger.TRACE)
Error trace:
Traceback (most recent call last):
File "/home/jsivil/Desktop/Proyectos/UNPAZ/jcheq/jcheq/jcheq.py", line 12, in <module>
from printing_systems import printing_systems
File "/home/jsivil/Desktop/Proyectos/UNPAZ/jcheq/jcheq/printing_systems/printing_systems.py", line 7, in <module>
from jcheq import JCheq
File "/home/jsivil/Desktop/Proyectos/UNPAZ/jcheq/jcheq/jcheq.py", line 12, in <module>
from printing_systems import printing_systems
ImportError: cannot import name 'printing_systems'
Moving the import statement in the function is commonly used to solve circular imports. It is handy in cases when restructuring your application would be too costly (if useful at all).
Another solution would be to move JCheq.logger into its own module that both jcheq.py and printing_systems/printing_systems.py would import.
Or, you could make logger.Logger a factory function backed by some registry (or simply memoize it) so that it returns the same logger when the same arguments are given. This way, printing_system.py would simple import logger instead of importing jcheq.

Can't solve a circular import

I've read this good text as a reference, but I still can't solve my circular problem:
import pygame
import python
import background
import player
import parser
class Game():
map1 = parser.Parser("map1")
map1.parse()
The parser.py module:
import os, sys
def replaceExtension(mapPath):
# content
class Parser():
def __init__(self, map, path="Maps/"):
replaceExtension(path)
# content
When I run my main file:
map1 = parser.Parser("map1")
AttributeError: 'module' object has no attribute 'Parser'
For some obscure reason it just does not find my Parser class.
There is a built-in module called parser.
That's the one that gets imported. You need to rename your module.
You can find more on import order here: http://docs.python.org/2/tutorial/modules.html#the-module-search-path

static method in Python not working

I'm learning by my self Python and I have a mind blowing issue, because I don't understand why is not working. I'm using PyDev and I've download version 2 of Python. I have this code:
class Utils:
#staticmethod
def hello():
print "Hi! I'm the Utils class"
Utils.hello() #Hi! I'm the Utils class
and everything is working fine at this point. But if I import the Utils class and call the static method from another module...
import Utils
Utils.hello()
I get this error:
Traceback (most recent call last):
File "C:\Users\migugonz\Desktop\Docs\Per Folder\WorkSpacePy\Rosalind\src\bioinformatics\stronghold\Pruebas.py", line 40, in <module>
Utils.hello()
AttributeError: 'module' object has no attribute 'hello'
I thing it can't be a big deal, but I've been searching a solution and as long I know this shlould be work.
I believe you need to do Utils.Utils.hello()
or import like from Utils import Utils

Using python static class C#/Java style, scope difference errors

I have two files, namely game.py and map.py. The following simplified code resides in them:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from datetime import *
from map import *
class Game:
Scene = QGraphicsScene
View = QGraphicsView
#staticmethod
def start():
Game.App = QApplication(sys.argv)
Game.Scene=QGraphicsScene();
Game.Scene.setBackgroundBrush(QBrush(QColor(Qt.green)));
Game.View=QGraphicsView(Game.Scene);
print Game
map=Map()
Game.App.exec_()
if __name__=='__main__':
Game.start()
and file map.py:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from game import *
class Map(QObject):
def __init__(self,parent=None):
super(Map,self).__init__(parent);
print Game
v=Game.View
print v
v.setWindowTitle("sth")
Running game.py results in
__main__.Game
game.Game
<class 'PyQt4.QtGui.QGraphicsView'>
Traceback (most recent call last):
File "/home/abiusx/workspace/borj/trunk/game.py", line 119, in <module>
Game.start()
File "/home/abiusx/workspace/borj/trunk/game.py", line 66, in start
map=Map()
File "/home/abiusx/workspace/borj/trunk/map.py", line 16, in __init__
v.setWindowTitle("asb")
TypeError: QWidget.setWindowTitle(QString): first argument of unbound method must have type 'QWidget'
The problem is, the code in map.py that references Game.View, detects it as a class (as defined in class body) but not what is overwritted on it (an actual instance).
Also Game is known as main.Game in game.py but as game.Game in map.py
Could anyone help me?
the code in map.py that references Game.View, detects it as a class
That's because View = QGraphicsView sets it to a class. It only becomes an instance when you run Game.start. (To be honest, I don't understand why you're setting this class variable to a class object initially, or why the Game class exists at all.)
Also Game is known as main.Game in game.py but as game.Game in map.py
The module name changes to __main__ when you run a module as a script.
Whenever a file is read in Python, when it reaches a class definition it defines that class.
In my scenario, game and map both relied on each other. this is a well known circular reference problem in python.
I added another module, main.py, used game and map in it, and game in map. Problem solved.

Categories