无法使用字符串调用函数

时间:2011-02-04 14:23:26

标签: python dynamic-function

我试图根据传入的字符串调用类中的函数。

我尝试按照此链接中的步骤操作: Calling a function of a module from a string with the function's name in Python

这是我的代码:

methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)

listOfPlayerFleets[currentPlayer].methodToCall(num)

我收到错误:

AttributeError:fleet instance has no attribute 'methodToCall'

为什么没有为methodToCall分配正确的方法名称?

我也试过

methodToCall = getattr(fleet, methodToCall)

然后我收到消息:

AttributeError: 'module' object has no attribute 'addCruiser'

好像getattr在我班上找不到我的方法。

listOfPlayerFleets是一个舰队对象列表

这是舰队对象的样子,你可以看到方法确实存在。

class fleet:
    """ Stores Fleet Numbers, Represents a fleet """

    ships = {'fighters':0, 'cruisers':0, 'capitols':0}
    attacking = False
    defending = False

    def __init__(self):
        self.ships = {'fighters':0, 'cruisers':0, 'capitols':0}
        self.attacking = False
        self.defending = False

    #add a Fighter
    def addFighter(self, numOfFighters):
        self.ships['fighters'] = numOfFighters


    #add a Cruiser
    def addCruiser(self, numOfCruisers):
        self.ships['cruisers'] = numOfCruisers

    #add a Capitol Ship
    def addCapitol(self, numOfCapitols):
        self.ships['capitols'] = numOfCapitols

4 个答案:

答案 0 :(得分:3)

你的methodToCall变量是一个绑定方法,这意味着你不需要在一个对象上调用它 - 它知道它将被调用的对象。例如,fleet.addFighter是一种未绑定的方法。打印repr(methodToCall)repr(fleet.addFighter)应该明确这一点。

你应该用这个:

methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)

methodToCall(num)

答案 1 :(得分:2)

应该这样做。

methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)

methodToCall(num)

getattr为您提供了该特定实例(listOfPlayerFleets[currentPlayer])的方法的引用,因此只需使用参数调用它。

答案 2 :(得分:1)

首先,这种事情很少与适当的解决方案相提并论,例如:使用字典,甚至不那么罕见。你应该有一个只有addShip(kind, num)的方法self.ships[kind] += num。更清洁,更容易扩展,干(不要重复自己),也可以更快地获得额外奖励。

至于错误:listOfPlayerFleets[currentPlayer].methodToCall(num)尝试调用名为methodToCall的方法(显然不存在。getattr(listOfPlayerFleets[currentPlayer], methodNameString)已经为您提供了所需的方法,而且它是绑定方法,即当您致电methodToCall()时,会传递正确的self

另一个错误('method' object has no ...)是因为模块与其中包含的东西(例如类)之间存在差异。我想class fleet位于名为fleet的模块中?然后你需要fleet.fleet。顺便说一下,类应该在CamelCase中命名 - 请参阅样式指南PEP 8

答案 3 :(得分:0)

你试过吗

func = getattr(obj, "method")
if callable(func):
  result = func(args)