将函数指定为对象的属性,然后在没有隐含的"自我"争论的情况下调用?

Bog*_*ist 5 python

Python允许您将预定义函数作为属性分配给类,例如

def fish_slap(fish):
    # do something

class dance(object):
    dance_move=fish_slap
Run Code Online (Sandbox Code Playgroud)

但是,如果我们试着说

d=dance()
d.dance_move("Halibut")
Run Code Online (Sandbox Code Playgroud)

我们得到以下错误

TypeError: fish_slap() takes exactly 1 arguement (2 given)
Run Code Online (Sandbox Code Playgroud)

Python似乎将此视为对象方法并提供隐含的"自我"参数.很公平,似乎我刚刚学会了以这种方式将函数作为属性赋值等同于直接在类中定义函数.我可以看到这是一个有用的功能.

但是,在这种情况下,这不是我想要的.在我的应用程序中,我将统计模型编码为不同的类,它们也有自己的"训练"方法,用于根据提供的数据训练模型参数.为此,您希望最小化(或最大化)需要提供的值的目标函数.一个简单的目标函数就是一个例子

def RMSE(predicted,observed):
    "Root mean squared error"
    return sp.sqrt(sp.mean((predicted-observed)**2))
Run Code Online (Sandbox Code Playgroud)

SciPy作为sp导入的位置.这些目标函数在单个.py文件中定义并在我的代码中使用,并且自然地作为独立函数存在,而不是作为具有隐含的"self"参数的类方法.

我希望能够将所需的目标函数设置为属性,以便模型对象的任何后续工作都可以使用该函数

some_model=SomeModel(initial_parameter_values_guess) 
some_model.objective_function = RMSE
some_model.train(training_data)
predictions_RMSE = some_model.predict()
some_mode.objective_function = MAE
predictions_MAE = some_model.predict()
Run Code Online (Sandbox Code Playgroud)

在这个例子中似乎我可以将目标函数作为参数传递给训练,但是在我的应用程序中有更多人想要做的事情,似乎更有意义的是能够设置/获得目标函数而不是而不是反复提供它作为一个论点.

有许多解决方法可以实现这种基本行为,但最流行的方法是什么?

请注意,我当前的代码是python2和python3兼容.如果有特定版本的解决方案,请指出.我正在运行python2以便能够使用matplotlib但是我试图确保代码是python3兼容的那个模块.

mgi*_*son 8

您可以使用静态方法

class dance(object):
    dance_move=staticmethod(fish_slap)
Run Code Online (Sandbox Code Playgroud)

请注意,staticmethod如果要分配实例的属性,则无需使用:

>>> def move():
...     print "disco party!"
... 
>>> class dance(object):
...     dance_move = staticmethod(move)
... 
>>> d = dance()
>>> d.dance_move()
disco party!
>>> d.break_it_down = move
>>> d.break_it_down()
disco party!
Run Code Online (Sandbox Code Playgroud)