哪个类应该存储查找表?

max*_*max 5 python oop

世界包含位于不同位置的代理,在任何位置只有一个代理.每个代理都知道他在哪里,但我还需要快速检查给定位置是否有代理.因此,我还保留了从地点到代理商的地图.我在决定一个问题,即该地图属于:class World,class Agent(作为一个阶级属性)或其他地方.

在下面我把查找表agent_locations放在class World.但现在代理商world.update_agent_location每次搬家都要打电话.这很烦人; 如果我稍后决定跟踪代理的其他事情,除了他们的位置之外Agent怎么办?我是否需要在整个代码中将回调添加回世界对象?

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)
Run Code Online (Sandbox Code Playgroud)

我可以把agent_locationsclass Agent作为一个类属性.但这只有在我有一个World对象时才有效.如果我后来决定实例化多个World对象,则查找表将需要特定于世界.

我相信有更好的解决方案......

编辑:我在代码中添加了几行来说明如何agent_locations使用.请注意,它仅用于内部Agent对象,但我不知道是否会永远保持这种情况.

Kar*_*ldt 1

它有助于 OOP 用is ahas a来谈论对象。AWorld 有一个列表Agents和 一个列表Locations。ALocation 有一个 Agent. AnAgent 有 a Location和 a 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
Run Code Online (Sandbox Code Playgroud)

通过向 a 添加新属性Location(例如地形)的心理练习,很容易看出这种封装的好处。同样,向 中添加新的东西Agent,例如武器,只需要类似于 的特定于武器的函数move()。请注意,根本World不需要参与其中move()。移动在Agent和 之间严格处理Location