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.
Advertisement
Answer
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.