Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:绑定一个未绑定的方法?_Python_Class_Methods_Bind - Fatal编程技术网

Python:绑定一个未绑定的方法?

Python:绑定一个未绑定的方法?,python,class,methods,bind,Python,Class,Methods,Bind,在Python中,有没有一种方法可以绑定未绑定的方法而不调用它 我正在编写一个wxPython程序,对于某个类,我决定将所有按钮的数据分组为一个类级元组列表,如下所示: class MyWidget(wx.Window): buttons = [("OK", OnOK), ("Cancel", OnCancel)] # ... def Setup(self): for text, handler in MyWidget.b

在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
来解决这个问题,但是有人知道是否有一种干净的、健康的、python式的方式将未绑定的方法绑定到一个实例,并继续在不调用它的情况下传递它吗?

这将
self
绑定到
处理程序

bound_handler = lambda *args, **kwargs: handler(self, *args, **kwargs)

这是通过将
self
作为第一个参数传递给函数来实现的
object.function()
只是
function(object)
的语法糖

这可以用干净的工具来完成。例如:

import types

def f(self): print self

class C(object): pass

meth = types.MethodType(f, C(), C) # Bind f to an instance of C
print meth # prints <bound method C.f of <__main__.C object at 0x01255E90>>
导入类型
def f(自我):打印自我
C类(对象):通过
meth=types.MethodType(f,C(),C)#将f绑定到C的实例
打印方法打印
所有函数也都是描述符,因此您可以通过调用它们的
\uu get\uu
方法来绑定它们:

bound_handler = handler.__get__(self, MyWidget)
这是R.Hettinger的优秀描述


作为一个自包含的示例,从以下内容中提取:


创建一个包含self的闭包在技术上不会绑定函数,但它是解决相同(或非常相似)根本问题的另一种方法。下面是一个简单的例子:

self.method = (lambda self: lambda args: self.do(args))(self)

聚会迟到了,但我带着一个类似的问题来到这里:我有一个类方法和一个实例,并且希望将实例应用到该方法

冒着过分简化OP问题的风险,我最终做了一些不那么神秘的事情,可能对其他来到这里的人有用(注意:我使用的是Python 3--YMMV)

考虑这个简单的类:

class Foo(object):

    def __init__(self, value):
        self._value = value

    def value(self):
        return self._value

    def set_value(self, value):
        self._value = value
以下是您可以使用它做的事情:

>>> meth = Foo.set_value   # the method
>>> a = Foo(12)            # a is an instance with value 12
>>> meth(a, 33)            # apply instance and method
>>> a.value()              # voila - the method was called
33

@Christopher-一种方法,它不受从中吸取的对象范围的约束,因此必须显式地传递self。我特别喜欢“壮观的火焰和我的眼泪”。是的,但这调用了该方法。问题是我需要能够将绑定方法作为可调用对象传递。我有unbound方法和我希望它绑定到的实例,但不知道如何在不立即调用它的情况下将它们放在一起。不,它没有,它只会在执行bound_handler()时调用该方法。定义lambda并不调用lambda。实际上,您可以使用
functools.partial
而不是定义lambda。不过,这并不能解决确切的问题。您仍然在处理
函数
而不是
实例方法
@Alan:
函数
的第一个参数与
实例方法
有什么区别;duck类型看不到区别。@LieRyan区别在于您仍然没有处理基本类型
functools.partial
会删除一些元数据,例如
\uuuu模块\uuu
。(我还想说一句,当我第一次看到我对这个答案的评论时,我非常害怕。)事实上,在我的问题中,我提到我已经在使用
functools.partial
,但我觉得必须有一种“更纯粹”的方法,因为很容易得到未绑定和绑定的方法。这很酷。我喜欢省略类型并取回“绑定方法?.f”的方式。我喜欢此解决方案而不是
MethodType
解决方案,因为它在py3k中的工作方式相同,而
MethodType
的参数已稍微更改。因此,用于将函数绑定到类实例的函数:
bind=lambda instance,func,asname:setattr(实例,asname,func.\uuuuu get\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
哈,你每天都会学到一些新东西。@Kazark在Python 3中,至少你也可以跳过提供类型,因为
\uuuu get\uuuu
将隐式地从对象参数中获取该类型。我甚至不确定提供它是否有任何作用,因为无论第一个参数是什么,我作为第二个参数提供的类型都没有区别是的一个实例。因此
bind=lambda instance,func,asname=None:setattr(instance,asname或func.\uuuuu name,func.\uuu get\uuuu(instance))
也应该这样做。(虽然我个人更喜欢将
bind
用作装饰程序,但那是另一回事。)哇,从来都不知道函数是描述符。这是一个非常优雅的设计,方法只是类“
\uuuu dict\uuuu
中的普通函数,属性访问通过正常的描述符协议为您提供了未绑定或绑定的方法。我一直认为这是
类型期间发生的某种魔法
+1这太棒了,但在您提供的URL的python文档中没有对它的引用。+1,我不希望在我的代码中调用神奇的函数(即
\uu get\uuu
)。我不知道您测试的是哪一版本的python,但在python 3.4上,
MethodType
函数有两个参数。函数和实例。因此,应该将其更改为
types.MethodType(f,C())
。这是一个修补实例方法的好方法:
wgt.flush=types.MethodType(lambda self:None,wgt)
实际上在文档中提到了它,但在另一个答案的描述符页面中:这并不能解决我的问题——我希望
meth
可以调用,而不必发送
a
参数(这就是我最初使用
functools.partial
)-但是,如果您不需要传递该方法,并且可以当场调用该方法,则这是更好的方法。此外,这在Python 2中的工作方式与在Python 3中的工作方式相同。
>>> meth = Foo.set_value   # the method
>>> a = Foo(12)            # a is an instance with value 12
>>> meth(a, 33)            # apply instance and method
>>> a.value()              # voila - the method was called
33