我正在使用名为test.py的文件测试我的两个类。我只是在学习编程,所以这只是一个练习程序。有一个地图集(地图),我可以在一张地图中放置多个“机器人”。
#test.py
from Atlas import Atlas
atlas = Atlas()
atlas.add_robot('rbt1')
#atlas.py
from Robot import Robot
class Atlas:
def __init__(self):
...
def add_robot(self, robot, zone = 'forrest'):
self.robot = Robot(robot)
print 'added robot %s to %s' % (robot, zone)
#robot.py
class Robot():
def __init__(self, rbt, zone = 'forrest'):
self.name = rbt
print "%s initiated" % rbt
def step(self, direction):
...
我使用代码“atlas.add_robot('rbt1')”将新机器人放入地图册。
我希望能够在test.py中使用诸如“rbt1.step('left')”之类的命令来控制机器人。
答案 0 :(得分:3)
您应该使用newRobot = Robot('rbt1')
在test.py中创建机器人,然后执行atlas.add_robot(newRobot)
。为此,我们传入整个机器人,而不是机器人名称。 Atlas不应该尝试初始化机器人,因为它是Atlas。它应该只关心Atlasses做什么:跟踪机器人的位置。
在编程中学习的一个好概念是允许哪些代码接触某些东西。在这种情况下,我们将在test.py中创建机器人(因此我们可以触摸它),然后将其传递给Atlas(因此Atlas可以触摸它)。这实际上是你问题的核心。以下是处理此问题的一些常规方法:
yourAtlas.robotsToZones(...)
相反)nonlocal
python中的关键字声明你打算这样做要更改控制流程,以免出现此问题:通过传入一个完整的机器人,可以使Atlas更加灵活。毕竟这是一个地图册。为什么阿特拉斯会负责制作机器人?
from collections import *
class Atlas(object):
def __init__(self):
self.zones = defaultdict(set)
def add_robot(self, robot, zone='forest')
self.robots[zone].add(robot)
或者你可以这样做: (可能更好,因为我们可能期望机器人改变区域)
class Atlas(object):
def __init__(self):
self.robotsToZones = {}
def add_robot(self, robot, zone='forest')
self.robotsToZones[robot.name] = zone
def robotsInWorlds(self):
return self.robotsToZones.keys() # .keys() not necessary, but hides representation
(如果你关心速度你实际上可以做到这两点......但你通常不应该关心速度,这需要确保两个结构同步)
此外,您应该只在一个位置存在数据。在你的情况下,机器人和地图集都需要知道机器人在哪个区域。这很糟糕,因为你必须确保这两个值始终相等且同步,导致不必要的头痛和并发症甚至可能是错误。解决方案是在robot.py中忽略机器人所在的区域:
class Robot(object):
def __init__(self, name):
self.name = name
机器人永远不需要弄清楚它在哪里;这是地图册的工作。如果test.py需要知道Robot的位置,它可以执行类似myAtlas.whereIs(myRobot)
的操作,只需return self.robotsToZones[robot.name]
。这称为模块化和关注点分离。
(旁注:以上假设你有一些其他的机制来跟踪哪些机器人在哪些区域,你没有坐标。如果你有step()
函数处理坐标,你将有判断你是否有全局或每区域坐标。后一种情况可能更容易,因为您需要定义的是区域边界如何拼接在一起;尽管如果你有Atlas定义非重叠,你可以做第一种情况( ick,可能的错误)区域在哪里。你也可以做一些像路标定义区域边界的东西,机器人在最近的路标区域。尽管每个区域由同样大小的矩形组成,通过网格表示,可能是最简单的。)
答案 1 :(得分:1)
您应该将机器人添加到Atlas
的列表中。不是self.robot = Robot(robot)
,而是将robots = []
添加到Atlas.__init__()
并在self.robots.append(Robot(robot))
中添加Atlas.add_robot(robot)
。然后,您可以通过列表(atlas.robots[0].step()
,atlas.robots[1].step()
等)访问它们。
答案 2 :(得分:1)
您应该可以通过atlas
引用在atlas.robot
内创建的机器人,因为这是您存储它的地方。你可以像这样创建一个指向它的新变量:
rbt1 = atlas.robot
然后你应该能够像你描述的那样引用它:
rbt1.step('left')
请注意,如果您希望atlas
能够拥有多个漫游器,则应考虑将机器人存储在list
内的dict
或atlas
对象中。