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 방식이 있는지 아는 사람이 있습니까?
답변
모든 함수도 설명자 이므로 해당 __get__메서드 를 호출하여 바인딩 할 수 있습니다 .
bound_handler = handler.__get__(self, MyWidget)
다음은 R. Hettinger의 훌륭한 설명자 가이드 입니다.
def bind(instance, func, as_name=None):
"""
Bind the function *func* to *instance*, with either provided name *as_name*
or the existing name of *func*. The provided *func* should accept the
instance as the first argument, i.e. "self".
"""
if as_name is None:
as_name = func.__name__
bound_method = func.__get__(instance, instance.__class__)
setattr(instance, as_name, bound_method)
return bound_method
class Thing:
def __init__(self, val):
self.val = val
something = Thing(21)
def double(self):
return 2 * self.val
bind(something, double)
something.double() # returns 42
답변
이것은 types.MethodType으로 깔끔하게 수행 할 수 있습니다 . 예:
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>>
답변
self가있는 클로저를 생성하면 기능이 기술적으로 바인딩되지는 않지만 동일한 (또는 매우 유사한) 근본적인 문제를 해결하는 다른 방법입니다. 다음은 간단한 예입니다.
self.method = (lambda self: lambda args: self.do(args))(self)
답변
이것은 다음에 바인딩 self됩니다 handler.
bound_handler = lambda *args, **kwargs: handler(self, *args, **kwargs)
이것은 self함수에 대한 첫 번째 인수로 전달 하여 작동합니다. object.function()의 구문 상 설탕입니다 function(object).
답변
파티에 늦었지만 비슷한 질문으로 여기에 왔습니다. 클래스 메서드와 인스턴스가 있고 인스턴스를 메서드에 적용하고 싶습니다.
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
답변
