在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)
Run Code Online (Sandbox Code Playgroud)
问题是,由于所有的值handler都是未绑定的方法,我的程序在一个壮观的火焰中爆炸,我哭泣.
我在网上寻找解决方案似乎应该是一个相对简单,可解决的问题.不幸的是我找不到任何东西.现在,我正在functools.partial尝试解决这个问题,但有没有人知道是否有一种干净,健康,Pythonic的方式将未绑定的方法绑定到一个实例并继续传递它而不调用它?
亲爱的python 3专家,
使用python2,可以执行以下操作(我知道这有点毛茸茸,但这不是重点:p):
class A(object):
def method(self, other):
print self, other
class B(object): pass
B.method = types.MethodType(A().method, None, B)
B.method() # print both A and B instances
Run Code Online (Sandbox Code Playgroud)
使用python3,没有更多的未绑定方法,只有函数.如果我想要相同的行为,听起来我要引入一个自定义描述符,例如:
class UnboundMethod:
"""unbound method wrapper necessary for python3 where we can't turn
arbitrary object into a method (no more unbound method and only function
are turned automatically to method when accessed through an instance)
"""
def __init__(self, callable):
self.callable = callable
def __get__(self, instance, objtype):
if instance is None:
return self.callable
return …Run Code Online (Sandbox Code Playgroud) 我知道如果你想为一个类实例添加一个方法,你不能像这样做一个简单的赋值:
>>> def print_var(self): # method to be added
print(self.var)
>>> class MyClass:
var = 5
>>> c = MyClass()
>>> c.print_var = print_var
Run Code Online (Sandbox Code Playgroud)
这确实会导致print_var行为像正常的函数,所以self参数不具有他的典型含义:
>>> c.print_var
<function print_var at 0x98e86ec>
>>> c.print_var()
Traceback (most recent call last):
File "<pyshell#149>", line 1, in <module>
c.print_var()
TypeError: print_var() takes exactly 1 argument (0 given)
Run Code Online (Sandbox Code Playgroud)
为了让函数被认为是一个方法(即将它绑定到实例),我曾经使用过这段代码:
>>> import types
>>> c.print_var = types.MethodType(print_var, c)
>>> c.print_var
<bound method MyClass.print_var of <__main__.MyClass object at 0x98a1bac>>
>>> c.print_var()
5
Run Code Online (Sandbox Code Playgroud)
但我发现它 …