我试图根据传入的字符串调用类中的函数。
我尝试按照此链接中的步骤操作: 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
答案 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)