5

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

def fish_slap(fish):
    # do something

class dance(object):
    dance_move=fish_slap

但是,如果我们尝试说

d=dance()
d.dance_move("Halibut")

我们得到以下错误

TypeError: fish_slap() takes exactly 1 arguement (2 given)

Python 似乎将其视为一种对象方法并提供隐含的“自我”参数。很公平,似乎我刚刚了解到以这种方式将函数分配为属性等同于直接在类中定义函数。我可以看到这是一个有用的功能。

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

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

其中 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()

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

有许多变通方法可以实现这种基本行为,但最简单的方法是什么?

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

4

1 回答 1

8

您可以使用静态方法

class dance(object):
    dance_move=staticmethod(fish_slap)

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!
于 2013-02-24T21:37:10.613 回答