Я пытаюсь вызвать функцию в классе на основе строки, в которую я прошел.
Я попытался выполнить следующие шаги по этой ссылке: Вызов функции модуля из строки с именем функции в 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
Ваша переменная methodToCall
является связанным методом, то есть вам не нужно вызывать ее на объекте - он знает объект, на который он будет вызываться. fleet.addFighter
, например, является несвязанным методом. Печать repr(methodToCall)
и repr(fleet.addFighter)
должна быть понятной.
Вы должны использовать это:
methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)
methodToCall(num)
eval
).
Это должно сделать это.
methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)
methodToCall(num)
getattr
дает ссылку на метод этого конкретного экземпляра (listOfPlayerFleets[currentPlayer]
), поэтому просто вызывайте его с параметрами.
Во-первых, такого рода вещи редко совпадают с правильным решением, например. используя словарь, и даже реже превосходит их. Вы можете использовать метод 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.
Вы пробовали
func = getattr(obj, "method")
if callable(func):
result = func(args)