如果一个函数(在类之外)需要使用类中的方法,我该如何调用该方法?

时间:2014-04-10 05:28:58

标签: python class methods

这是班级:

class MinerNotFullAction:
   def __init__(self, entity, image_store):
      self.entity = entity
      self.image_store = image_store

   def miner_to_ore(self, world, ore):
      entity_pt = entities.get_position(self.entity)
      if not ore:
         return ([entity_pt], False)
      ore_pt = entities.get_position(ore)
      obj = point.Point(0, 0)
      if obj.adjacent(entity_pt, ore_pt):
         entities.set_resource_count(self.entity,
            1 + entities.get_resource_count(self.entity))
         remove_entity(world, ore)
         return ([ore_pt], True)
      else:
         new_pt = next_position(world, entity_pt, ore_pt)
         return (worldmodel.move_entity(world, entity, new_pt), False)

这是同一个文件中的函数,但它在类之外:

def miner_not_full_action(world, action, ticks):
   entity = action.entity
   entity_pt = entities.get_position(entity)
   ore = find_nearest(world, entity_pt, entities.Ore)
   (tiles, found) = MinerNotFullAction.miner_to_ore(world, entity, ore)

   if found:
      entity = try_transform_miner(world, entity, try_transform_miner_not_full)

   schedule_action(world, entity,
      create_miner_action(entity, action.image_store),
      ticks + entities.get_rate(entity))
   return tiles

如果查看函数def miner_not_full_action,您会看到以下行:(tiles, found) = miner_to_ore(world, entity, ore).请注意,在此函数中,它正在调用方法miner_to_ore(来自类我上面已提供)。

我的问题是,重写这行代码的正确方法是什么,以便函数可以在类中使用此方法(即使函数本身在类之外)?谢谢!

2 个答案:

答案 0 :(得分:1)

示例:

class MinerNotFullAction:
    def __init__(self,):
        pass

    def miner_to_ore(self, world, ore):
       print('works in', self.__class__.__name__)


# Inherit from MinerNotFullAction to get
# its methods and attributes
class WorldClass(MinerNotFullAction):
    pass

# Helper function
def miner_to_ore(arg1, arg2, arg3):
    arg1.miner_to_ore(arg2, arg3)


m = MinerNotFullAction()
w = WorldClass()

miner_to_ore(m, 1, 2)
miner_to_ore(w, 1, 2)

# or cleaner and preferred way:
# m.miner_to_ore(1, 2)
# w.miner_to_ore(1, 2)

打印

works in MinerNotFullAction
works in WorldClass

因此,在您的情况下,您可以创建单独的函数miner_to_ore(如下所述)并从world继承MinerNotFullAction对象的类。然后以下内容将起作用:

(tiles, found) = miner_to_ore(world, entity, ore)

答案 1 :(得分:0)

如果您拥有此类的对象或者可以构造一个类,则只能从外部调用类的方法。除外,如果它是静态方法或类方法。

在您的示例中,您想要使用

中的内容
class MinerNotFullAction:
   def __init__(self, entity, image_store):
      self.entity = entity
      self.image_store = image_store

   def miner_to_ore(self, world, ore):
       ...

def miner_not_full_action(world, action, ticks):
   entity = action.entity
   entity_pt = entities.get_position(entity)
   ore = find_nearest(world, entity_pt, entities.Ore)
   (tiles, found) = MinerNotFullAction.miner_to_ore(world, entity, ore)
   ...

所以,问题是:你在这里有适当的选择对象吗?

如果是这样(action听起来像是一个合适的候选人),你可以做到

(tiles, found) = action.miner_to_ore(world, ore)

为了执行你的任务。

从另一方面看:如果您调用此方法,则必须将某些内容视为self。这应该是这个类的一个实例。如果你没有这样的东西,你必须创建一个。否则,self在该方法中毫无意义。

简单的例子:

def miner_not_full_action(world, action, ticks):
    # 1. call it via the class. That may or may not work, but you have to provide an action object as the first argument.
    try1 = MinerNotFullAction.miner_to_ore(action, world, ore)
    # 2. call it regularly (as already mentioned), equivalent to 1.
    try2 = action.miner_to_ore(world, ore)

    # If we don't have such an object? Then we create one:
    ac = MinerNotFullAction()
    # and use it to call:
    try3 = ac.miner_to_ore(world, ore)