Reputation: 7809
I'm attempting to pass a class method as an argument to another class method. Below is an example...
import time
class MyClass(object):
def doSomething(self,argument2,argument3):
print argument2,argument3
def attemptTenTimes(self,fun,*args):
attempt = 0
while True:
try:
print 'Number of arguments: %s' % len(*args)
print args
output = fun(*args)
return output
except Exception as e:
print 'Exception: %s' % e
attempt += 1
time.sleep(10)
if attempt >= 10: return
else: continue
MC = MyClass()
MC.attemptTenTimes(MC.doSomething,(MC,'argument2','argument3',))
The output is....
Number of arguments: 3
((<__main__.MyClass object at 0x7f7e6be4e390>, 'argument2', 'argument3'),)
Exception: doSomething() takes exactly 3 arguments (2 given)
Number of arguments: 3
((<__main__.MyClass object at 0x7f7e6be4e390>, 'argument2', 'argument3'),)
Exception: doSomething() takes exactly 3 arguments (2 given)
Number of arguments: 3
((<__main__.MyClass object at 0x7f7e6be4e390>, 'argument2', 'argument3'),)
Exception: doSomething() takes exactly 3 arguments (2 given).............
I am passing three arguments to the function doSomething, however, this exception keeps coming up. I've used functions as arguments to other functions before, but this is my first time doing it within the context of a class. Any help would be appreciated. Thanks.
Upvotes: 0
Views: 90
Reputation: 17168
You've not passed three arguments; you passed two. You need this:
MC.attemptTenTimes(MC.doSomething,*('argument2','argument3'))
or this (equivalent):
MC.attemptTenTimes(MC.doSomething,'argument2','argument3')
The attemptTenTimes
function has the parameter *args
, which collects positional arguments into a tuple referred to locally as args
. You're passing it the whole tuple as the only positional argument, so locally you have a variable named args
that looks like ((MC,'argument2','argument3'),)
. As a result, when you unpack it and pass it to your function, you're just passing the inner tuple.
As an aside, you also shouldn't be unpacking args when you pass it to len
, because that'll throw an error. You just want len(args)
on line 12 up there.
Alternately, you could change your attemptTenTimes function signature to this:
def attemptTenTimes(self,fun,args):
You could then pass the whole args tuple to it, as you were originally doing. I believe using *args
is more standard, though, and personally I think it's clearer.
Upvotes: 1