I have to try to move from the non-class-based coding style into class-based coding style, but facing an issue. The optimize() function takes a callback function mycallback(). The code works perfectly fine in Non-class-based method, but when I moved it to class-based method, I got an error "mycallback() takes exactly 3 arguments (1 given)".
What is the right way to pass a callback function in the class-based method?
(A) Non-class-based method:
def mycallback(model, where):
pass
model = Model()
model.optimize(mycallback)
(B) Class-based method:
class A:
def __init__(self):
self.model = Model()
def solve(self):
# Try method 1:
self.model.optimize(self.mycallback()) <--- Error: mycallback() takes exactly 3 arguments (1 given)
# Try method 2:
# self.model.optimize(self.mycallback) <--- Error: Callback argument must be a function
def mycallback(self, model, where):
pass
While this is a problem regarding passing a callback function to Gurobi's (an optimization solver) built-in function, I believe it is a more general question on how to pass a callback function defined in a class to another function in Python.
Error For method 2:
self.model.optimize(self.mycallback)
File "model.pxi", line 458, in gurobipy.Model.optimize (../../src/python/gurobipy.c:34263)
gurobipy.GurobiError: Callback argument must be a function
Looks like it is likely to be Gurobi API issue. Wonder if any Gurobi dev will response.
In general, self.model.optimize(self.mycallback)
should work (note: no parens after mycallback
).
It may fail if the code serializes the callable e.g., to be send via pipe/socket to another process (even on different machine):
from multiprocessing import Pool
class C:
def method(self, i):
return "called", i
if __name__=="__main__":
print(Pool().map(C().method, range(10)))
It works on recent Python versions where methods are pickable.
Or it may fail if model.optimize()
has a bug and check for the exact function type instead of accepting any callable.