如何绑定未绑定的方法而不调用它?
在Python中,有没有一种方法可以绑定未绑定的方法而不调用它?
我正在编写一个 wxPython 程序,对于某个类,我决定将所有按钮的数据作为类级元组列表分组在一起会很好,如下所示:
class MyWidget(wx.Window):
buttons = [
("OK", OnOK),
("Cancel", OnCancel)
]
...
def setup(self):
for text, handler in MyWidget.buttons:
# This following line is the problem line.
b = wx.Button(parent, label=text).bind(wx.EVT_BUTTON, handler)
问题是,因为handler
是未绑定的方法,我的程序在一场壮观的大火中爆炸,我哭了。
我在网上寻找一个似乎应该是相对简单、可解决的问题的解决方案。 不幸的是我找不到任何东西。 现在,我正在使用 functools.partial 来解决这个问题,但是有谁知道是否有一种干净、健康、Pythonic 的方式将未绑定的方法绑定到实例并继续传递它而无需调用它?
In Python, is there a way to bind an unbound method without calling it?
I am writing a wxPython program, and for a certain class I decided it would be nice to group the data of all of my buttons together as a class-level list of tuples, like so:
class MyWidget(wx.Window):
buttons = [
("OK", OnOK),
("Cancel", OnCancel)
]
...
def setup(self):
for text, handler in MyWidget.buttons:
# This following line is the problem line.
b = wx.Button(parent, label=text).bind(wx.EVT_BUTTON, handler)
The problem is, since all of the values of handler
are unbound methods, my program explodes in a spectacular blaze and I weep.
I was looking around online for a solution to what seems like should be a relatively straightforward, solvable problem. Unfortunately I couldn’t find anything. Right now, I am using functools.partial
to work around this, but does anyone know if there’s a clean-feeling, healthy, Pythonic way to bind an unbound method to an instance and continue passing it around without calling it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
所有函数也是描述符,因此您可以通过调用它们的 __get__ 方法来绑定它们:
这是 R. Hettinger 的优秀 描述符指南。
作为一个独立的示例,来自 Keith 的 评论:
All functions are also descriptors, so you can bind them by calling their
__get__
method:Here's R. Hettinger's excellent guide to descriptors.
As a self-contained example pulled from Keith's comment:
这可以通过
types.MethodType
< 来完成/a>:This can be done with
types.MethodType
:使用闭包,也称为封闭表达式(与开放表达式相反),这是一个没有自由变量:
这里
handler
和self
是内部lambda表达式中的自由变量,外部 lambda 表达式中的绑定变量,而args
和kwargs
是两个表达式中的绑定变量内部和外部 lambda 表达式,因此外部 lambda 表达式是一个闭包。With a closure, also known as a closed expression (as opposed to an open expression), which is an expression without free variables:
Here
handler
andself
are free variables in the inner lambda expression and bound variables in the outer lambda expression, andargs
andkwargs
are bound variables in both the inner and outer lambda expressions, so the outer lambda expression is a closure.这会将
self
绑定到handler
:这通过将
self
作为第一个参数传递给函数来实现。obj.f()
只是f(obj)
的语法糖。This will bind
self
tohandler
:This works by passing
self
as the first argument to the function.obj.f()
is just syntactic sugar forf(obj)
.聚会迟到了,但我带着类似的问题来到这里:我有一个类方法和一个实例,并且想要将该实例应用于该方法。
冒着过度简化OP问题的风险,我最终做了一些不太神秘的事情,这可能对到达这里的其他人有用(警告:我正在Python 3 - YMMV中工作)。
考虑这个简单的类:
您可以使用它执行以下操作:
Late to the party, but I came here with a similar question: I have a class method and an instance, and want to apply the instance to the method.
At the risk of oversimplifying the OP's question, I ended up doing something less mysterious that may be useful to others who arrive here (caveat: I'm working in Python 3 -- YMMV).
Consider this simple class:
Here's what you can do with it:
扩展@Keith Pinson的答案,它使用闭包和@brian-brazil 的答案 没有,这就是为什么前者是正确的。
带闭包的示例:
外部 lambda 表达式已关闭,因此其绑定变量
handler
和self
无法重新绑定。__get__
、types.MethodType
和functools.partial
具有相同的行为。没有闭包的示例:
lambda 表达式是开放的,因此它的自由变量
handler
和self
可以被重新绑定。To expand on @Keith Pinson’s answer which uses a closure and @brian-brazil’s answer which does not, here is why the former is correct.
Example with a closure:
The outer lambda expression is closed so its bound variables
handler
andself
cannot be rebound.__get__
,types.MethodType
, andfunctools.partial
have the same behaviour.Example without a closure:
The lambda expression is open so its free variables
handler
andself
can be rebound.