Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can classes work in the same file but if they are separated then imported properly there are errors?

Tags:

python

I am new to programming, I have made a little program just to learn how to use python and I made this.

It works just fine if I have it in one file, but when I separate it into three files calles Atlas.py , Robot.py and Test.py.

I get an error: "Undefined Variable: Atlas" in the robot class on the init line.

I have commented which file it is inside in a comment right above.

#Atlas.py
class Atlas:

def __init__(self):
    self.robots = []
    self.currently_occupied = {}

def add_robot(self, robot):
    self.robots.append(robot)
    self.currently_occupied = {robot:[]}


#Robot.py
class Robot():

def __init__(self, rbt, atlas = Atlas): #This is the main error:"Undefined Variable: Atlas" This happens after i separate the file
    self.xpos = 0
    self.ypos = 0
    self.atlas = atlas()
    self.atlas.add_robot(rbt)
    self.name = rbt

def walk(self, axis, steps=2):
    ....

#Test.py
robot1 = Robot("robot1")

I put these classes into the corresponding files and Test.py looks like this now:

#Test.py
import Robot
robot1 = Robot("robot1")
like image 328
user1082764 Avatar asked May 18 '12 01:05

user1082764


People also ask

Should each class be in a separate file?

It is good practice to do so. You can easily find the class if you name the file after the class.


2 Answers

In Robot.py your first line should be (assuming the file is called Atlas.py):

from Atlas import Atlas

meaning "from the Atlas.py file (also known as the Atlas module) import the Atlas class", so the Atlas variable becomes available in the Robot.py file (also known as the Robot module).

IOW, if you need the Robot class in another file (and it still lives in the Robot module at Robot.py), you'll need to add "from Robot import Robot" to that new file.

I suggest you read as much of the Python Tutorial as you can. Otherwise, your current problems are more directly about modules, so read that section.

like image 138
TryPyPy Avatar answered Nov 08 '22 21:11

TryPyPy


Python is cool in this way, as the understanding will lead you why Python gets simpler as you learn more.

Python just executes scripts from top to bottom, in a namespace dictionary.

In the first example, your code looks like:

a 10 line class statement adds Atlas to the default namespace
a 12 line class statement adds Robot to the default namespace
robot1 = Robot("robot1")

and that last line is really rewritten as a function call:

robot1 = default_namespace.Robot.init("robot1") 
# plus a bit of magic to create an instance and grab the return value.

which works because the Robot class is its own namespace of type Class.

When you separate the files, and hit this code:

import Robot

it means:

if we haven't already imported the module Robot:
    find the file named Robot.py
    execute it, line by line, and keep the kept_namespace
    default_namespace.Robot = kept_namespace

So, in our main line test:

>>> print type(Robot), dir(Robot)
<type 'module'>, [..., 'Robot']
>>> print type(Robot.Robot), dir(Robot.Robot)
<type 'classobj'>, [..., '__init__', 'walk']
>>> robot1 = Robot.Robot("robot1")

To make it simpler, or more confusing, the default namespace, modules, and classes are all dict objects with a little typing magic to cut down on coding errors.

like image 30
Charles Merriam Avatar answered Nov 08 '22 20:11

Charles Merriam