将未绑定的python函数存储在类对象中

Posted

技术标签:

【中文标题】将未绑定的python函数存储在类对象中【英文标题】:storing unbound python functions in a class object 【发布时间】:2010-09-24 13:22:51 【问题描述】:

我正在尝试在 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 的文件中: 导入foo

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

但是,我收到以下错误:

TypeError: 必须以数据实例作为第一个参数调用未绑定的方法 f()(取而代之的是 int 实例)

我想这很公平 - python 将 d.myFunction 视为类方法。但是,我希望它把它当作一个普通函数来对待——这样我就可以调用它,而不必在 myFunction 定义中添加一个未使用的“self”参数。

所以问题是:

如何将函数存储在类对象中而不绑定到该类?

【问题讨论】:

我认为您打算使用:d.fn(1,2,3) 而不是 d.myFunctions(1,2,3) 是的,我想你的意思是 d.fn() 解决方案如下,但你为什么要这个? 【参考方案1】:
data.fn = staticmethod(myFunction)

应该可以解决问题。

【讨论】:

这是正确的答案和语法,因为函数是在别处定义的。【参考方案2】:

你可以做的是:

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

d.fn(1,2,3)

这可能不是您想要的,但确实有效。

【讨论】:

【参考方案3】:

感谢 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 模块来运行插件代码,然后提取上面提到的类对象 - 这给了我配置数据和插件功能,因此我可以干净地运行它(无需污染我的命名空间)。

整个过程在同一输入上针对不同的插件重复多次,似乎对我来说效果很好。

【讨论】:

"所有插件都使用修改后的 sys.path 调用" 您是在 try/finally 块中临时修改 sys.path 还是有办法“隐藏”全局 sys.path? 请使用您问题上的编辑链接添加其他信息。 “发布答案”按钮应仅用于问题的完整答案。

以上是关于将未绑定的python函数存储在类对象中的主要内容,如果未能解决你的问题,请参考以下文章

python-属性的查找与绑定方法

Python学习之绑定方法与非绑定方法

面向对象——绑定方法与非绑定方法

Python——类和对象

绑定方法与非绑定方法

day07面向对象进阶