在类对象中存储无绑定的Python函数

18 投票
3 回答
3311 浏览
提问于 2025-04-11 20:31

我正在尝试在Python中做以下事情:

在一个叫做foo.py的文件里:

# simple function that does something:
def myFunction(a,b,c):
  print "call to myFunction:",a,b,c

# class used to store some data:
class data:
  fn = None

# assign function to the class for storage.
data.fn = myFunction

然后在另一个叫做bar.py的文件里:

import foo

d = foo.data
d.fn(1,2,3)

但是我遇到了以下错误:

TypeError: unbound method f() must be called with data instance as first argument (got int instance instead)

这个错误我觉得是合理的——Python把d.myFunction当成了一个类方法。不过,我希望它把这个方法当成普通函数来处理,这样我就可以调用它,而不需要在myFunction的定义中加一个没用的'self'参数。

所以问题是:

我该如何在一个类对象中存储一个函数,而不让这个函数绑定到那个类上呢?

3 个回答

0

感谢Andre的回答,真是太简单了!

对于在意这个问题的朋友们,我想我应该把整个问题的背景都说清楚。这里就是背景:

在我的应用程序中,用户可以用Python编写插件。他们需要定义一个函数,并且这个函数的参数要符合一定的要求,但我不想强制他们使用特定的命名规则。

所以,只要用户写的函数参数数量和类型正确,他们只需要做一些类似这样的事情(记住,这就是插件代码):

# this is my custom code - all plugins are called with a modified sys.path, so this
# imports some magic python code that defines the functions used below.
from specialPluginHelperModule import *

# define the function that does all the work in this plugin:
def mySpecialFn(paramA, paramB, paramC):
    # do some work here with the parameters above:
    pass

# set the above function:
setPluginFunction(mySpecialFn)

调用setPluginFunction会把这个函数对象放到一个隐藏的类对象里(还有其他和插件配置相关的内容,这个例子稍微简化了一下)。当主应用程序想要运行这个函数时,我会使用runpy模块来执行插件代码,然后提取上面提到的类对象——这样我就能得到配置数据和插件函数,从而干净地运行它(不污染我的命名空间)。

这个过程会针对不同的插件在相同的输入上重复多次,效果对我来说非常好。

1

你可以这样做:

d = foo.data()
d.fn = myFunction

d.fn(1,2,3)

这可能不是你想要的完全样子,但确实可以实现。

27
data.fn = staticmethod(myFunction)

这样做就可以了。

撰写回答