1

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

我尝试按照此链接中的步骤操作: 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

4 回答 4

3

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

你应该使用这个:

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

methodToCall(num)
于 2011-02-04T14:29:26.800 回答
2

那应该这样做。

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

methodToCall(num)

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

于 2011-02-04T14:29:20.197 回答
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

于 2011-02-04T14:31:43.673 回答
0

你试过了吗

func = getattr(obj, "method")
if callable(func):
  result = func(args)
于 2011-02-04T14:37:38.040 回答