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