Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 哪个类应该存储查找表?_Python_Oop - Fatal编程技术网

Python 哪个类应该存储查找表?

Python 哪个类应该存储查找表?,python,oop,Python,Oop,世界上有不同位置的代理,任何位置都只有一个代理。每个特工都知道他在哪里,但我还需要快速检查给定地点是否有特工。因此,我还维护了从位置到代理的地图。我在确定此映射所属的位置时遇到问题:类世界、类代理(作为类属性)或其他位置 在下面的部分中,我将查找表agent\u locations放在class-World中。但现在代理必须调用world.update\u agent\u location。这很烦人,;如果我以后决定跟踪关于代理的其他事情,除了它们的位置,我是否需要在代理代码中添加对world对

世界上有不同位置的代理,任何位置都只有一个代理。每个特工都知道他在哪里,但我还需要快速检查给定地点是否有特工。因此,我还维护了从位置到代理的地图。我在确定此映射所属的位置时遇到问题:
类世界
类代理
(作为类属性)或其他位置

在下面的部分中,我将查找表
agent\u locations
放在
class-World
中。但现在代理必须调用
world.update\u agent\u location
。这很烦人,;如果我以后决定跟踪关于代理的其他事情,除了它们的位置,我是否需要在
代理
代码中添加对world对象的调用

class World:
  def __init__(self, n_agents):
    # ...
    self.agents = []
    self.agent_locations = {}
    for id in range(n_agents):
      x, y = self.find_location()
      agent = Agent(self,x,y)
      self.agents.append(agent)
      self.agent_locations[x,y] = agent
  def update_agent_location(self, agent, x, y):
    del self.agent_locations[agent.x, agent.y]
    self.agent_locations[x, y] = agent
  def update(self): # next step in the simulation
    for agent in self.agents:
      agent.update() # next step for this agent
  # ...

class Agent:
  def __init__(self, world, x, y):
    self.world = world
    self.x, self.y = x, y
  def move(self, x1, y1):
    self.world.update_agent_location(self, x1, y1)
    self.x, self.y = x1, y1
  def update():
    # find a good location that is not occupied and move there
    for x, y in self.valid_locations():
      if not self.location_is_good(x, y):
        continue
      if self.world.agent_locations[x, y]: # location occupied
        continue
      self.move(x, y)
我可以将
agent\u locations
作为class属性放在
class-agent
中。但只有当我有一个
World
对象时,这才有效。如果我以后决定实例化多个
World
对象,那么查找表需要是特定于世界的

我相信有更好的解决办法


编辑:我在代码中添加了几行,以显示如何使用
agent\u locations
。请注意,它只在
代理
对象内部使用,但我不知道这种情况是否会一直持续下去。

对不起,我不理解这个问题。“当代理决定移动到哪里时,他会检查以确保不会遇到其他代理”。显然,一个位置可以有0或1个代理。当然Location类有一个agent属性

locn = self.where_to_move()
if locn.agent is None:
    self.move(locn)
elif locn.agent is self:
    raise ConfusedAgentError()
else:
    self.execute_plan_B()

好的,我想我可以提供我的答案,这可能更像是一种观点,而不是一个明确的“做这个”(我没有任何编程方面的正式培训)

我认为您
代理位置
应该是每个
世界
实例的成员。

我主要从界面的角度来思考。在我看来,世界级应该负责管理你们世界的资源,在这种情况下是空间。由于
World
是空间的管理者,代理应该询问他们的世界空间是否可用(即未占用),而不是彼此。因此,我认为您的
self.location\u很好
更合适的调用是
self.world.is\u location\u可用(x,y)
[1]

这使得世界自然要负责查找给定空间的可用性。世界级还可能有其他变量决定空间是否可用。如果那里有灌木丛呢?或者别的什么。您可能已经为每个世界的
(x,y)
坐标准备了某种表格。“被占用”可能是这些对象的属性

此外:您的世界已经知道每个代理的状态(通过self.agents中代理的
[(agent.x,agent.y)]
[2])。
agent\u locations
dict本质上是这些属性的索引或缓存,因此属于
World

class Agent:
    def __init__(self, world):
        self.location = None
        self.world = world

    def move(self, new_location):
        if self.location is not None:
            self.location.agent = None
        new_location.agent = self
        self.location = new_location

    def update(self):
        for new_location in self.world.locations:
            if self.location_is_good(new_location):
                self.move(new_location)

    def location_is_good(self, location):
        if location.agent is not None:
            return False

class Location:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.agent = None
关于将国家送回
世界的痛苦
。。。好吧,你不可能通过让
Agent
来解决这个问题。但是做
update\u agent\u location(self,agent,x,y)
是完全多余的,因为
x==agent.x;y==agent.y
(如果将调用它的行颠倒过来)。您只需在World中使用一种方法,
update\u agent\u state(self,agent)
,World就可以使用它来更新索引。您甚至可以提交一个额外的参数来描述状态更改的类型(如果您不想每次更新所有属性)

诸如此类(请看我的脚注)

[1] 当然,除非一个位置的“优点”取决于其他变量,而不是空间是自由的。例如,如果你只应该移动到(x,y),如果1)位置可用,2)代理有1000美元支付车票,那么你应该有一个
代理。你可以移动到(x,y)
,这反过来调用世界的方法,并检查它的钱包


[2] 我假设你的
self.agents={}
是一个打字错误,因为你不能
append
在dict上。你是说一个列表(
[]
)对吗

用is a和has a来谈论对象有助于OOP。
World
有一个
代理列表
和一个
位置列表
位置
有一个
代理
代理
有一个
位置
和一个
世界

class Agent:
    def __init__(self, world):
        self.location = None
        self.world = world

    def move(self, new_location):
        if self.location is not None:
            self.location.agent = None
        new_location.agent = self
        self.location = new_location

    def update(self):
        for new_location in self.world.locations:
            if self.location_is_good(new_location):
                self.move(new_location)

    def location_is_good(self, location):
        if location.agent is not None:
            return False

class Location:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.agent = None

通过将新属性添加到
位置
(如地形)的心理练习,很容易看到这种封装的好处。同样,向
代理添加新的东西,例如武器,只需要类似于
move()
的特定于武器的功能。请注意,
World
根本不需要参与
move()
。在
代理
位置

之间严格处理移动,您不需要更新
代理。代理位置
吗?您的快速检查必须有多快?你们有多少特工?如果你没有那么多(相对的),你可以迭代一个世界的代理,检查他们的位置。当代理决定移动到哪里时,他会检查以确保不会遇到其他代理。如果我迭代所有代理来检查这一点,我将在任何代理移动时查找每个代理的位置(执行
n_-agents
操作)。更新查找表时,每个
移动只需要一次操作。但是,您提供的代码没有检查这一点<代码>更新\u代理\u位置
只是覆盖在
(x,y)
之前的任何人。。。无论如何,将查找表移动到
代理
类真的能解决问题吗?您是否仍然需要调用
代理。更新\u Agent\u位置
?让我添加一个示例代码来演示如何使用它。我只是没有把它包括在内