I am trying to call a function in a class based on the string I passed in.
I tried following the steps at this link: Calling a function of a module from a string with the function's name in Python
Here is my code:
methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)
listOfPlayerFleets[currentPlayer].methodToCall(num)
I get the error:
AttributeError:fleet instance has no attribute 'methodToCall'
Any ideas as to why methodToCall isn't being assigned my correct method name?
I also tried
methodToCall = getattr(fleet, methodToCall)
then I get the message:
AttributeError: 'module' object has no attribute 'addCruiser'
Its as if the getattr can't find my methods in my class.
the listOfPlayerFleets is a list of fleet objects
Here is what the fleet object looks like you can see the methods do really exist.
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
Your methodToCall variable is a bound method, meaning you don't need to call it on an object--it knows the object it will be called on. fleet.addFighter, for example, is an unbound method. Printing repr(methodToCall) and repr(fleet.addFighter) should make this clear.
You should use this:
methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)
methodToCall(num)
That should do it.
methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)
methodToCall(num)
The getattr gives you a reference to the method of that specific instance (listOfPlayerFleets[currentPlayer]), so just call it with the parameters.
First off, this kind of thing is rarely on par with a proper solution, e.g. using dictionary, and even less rarely superior to those. You sould propably have a method addShip(kind, num) that just does self.ships[kind] += num. Much cleaner, easier to extend, DRY (don't repeat yourself) and as an extra bonus also faster.
As for the errors: listOfPlayerFleets[currentPlayer].methodToCall(num) tries to call the method called methodToCall (which obviously doesn't exist. getattr(listOfPlayerFleets[currentPlayer], methodNameString) already got you the method you want, and it's a bound method, i.e. when you call methodToCall(), the right self is passed.
The other error ('method' object has no ...) is because there's a difference between modules and the things (e.g. classes) contained in it. I suppose the class fleet is in a module called fleet? Then you need fleet.fleet. By the way, classes should be named in CamelCase - see the style guide, PEP 8.
Did you try
func = getattr(obj, "method")
if callable(func):
result = func(args)
加载中,请稍侯......
精彩评论