Python在类中传递回调函数

问题描述 投票:6回答:2

我必须尝试从基于非类的编码风格转变为基于类的编码风格,但面临一个问题。 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开发者会做出回应。

python python-2.7 gurobi
2个回答
1
投票

一般来说,self.model.optimize(self.mycallback)应该工作(注意:在mycallback之后没有parens)。

如果代码序列化可调用代码,例如,通过管道/套接字发送到另一个进程(即使在不同的机器上),它可能会失败:

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()有错误并检查确切的函数类型而不是接受任何可调用,它可能会失败。


0
投票

似乎如果从对象中删除回调,那么它可以正常工作。您可以将其用作解决方法,直到您可以在课堂上进行回调。也就是说,从班级内拨打这一行......

def solve(self):
    self.model.optimize(mycallback)

...到班级以外的这个功能。

def mycallback(self, model, where):     
    pass

一点都不优雅,但希望开发人员能够加入进来。

© www.soinside.com 2019 - 2024. All rights reserved.