我必须尝试从基于非类的编码风格转变为基于类的编码风格,但面临一个问题。 optimize()函数采用回调函数mycallback()。代码在非基于类的方法中完美地运行,但是当我将它移动到基于类的方法时,我得到一个错误“mycallback()正好接受3个参数(给定1个)”。
在基于类的方法中传递回调函数的正确方法是什么?
(A)非基于类别的方法:
def mycallback(model, where):
pass
model = Model()
model.optimize(mycallback)
(B)基于类的方法:
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
虽然这是一个将回调函数传递给Gurobi(一个优化求解器)内置函数的问题,但我认为这是一个关于如何将类中定义的回调函数传递给Python中的另一个函数的更普遍的问题。
错误方法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
看起来很可能是Gurobi API问题。不知道是否有任何Gurobi开发者会做出回应。
答案 0 :(得分:1)
一般情况下,self.model.optimize(self.mycallback)
应该有效(注意:mycallback
之后没有任何问题。)
如果代码序列化可调用代码,例如,通过管道/套接字发送到另一个进程(即使在不同的机器上),它可能会失败:
from multiprocessing import Pool
class C:
def method(self, i):
return "called", i
if __name__=="__main__":
print(Pool().map(C().method, range(10)))
它适用于最近的Python版本,其中方法是可选择的。
如果model.optimize()
有错误并且检查确切的函数类型而不是接受任何可调用函数,它可能会失败。
答案 1 :(得分:1)
这个问题在 gurobi 9.1
中仍然存在。我发现一个简单的解决方法是将回调放在类中的方法中,例如:
def solve(self):
self.model.update()
def lazyCallback(model, where):
...
self.model.optimize(lazyCallback)
答案 2 :(得分:0)
似乎如果从对象中删除回调,那么它可以工作。您可以将其用作解决方法,直到您可以在课堂上进行回调。也就是说,从班级中调用这一行......
def solve(self):
self.model.optimize(mycallback)
...到班级以外的这个功能。
def mycallback(self, model, where):
pass
根本不优雅,但希望开发人员能够加入。