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")
It is good practice to do so. You can easily find the class if you name the file after the class.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With