Ответ 1
Все функции также являются дескрипторами, поэтому вы можете связать их, вызвав их метод __get__
:
bound_handler = handler.__get__(self, MyWidget)
Здесь Р. Хеттингер отлично описывает руководство для дескрипторов.
В 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
, чтобы обойти это, но кто-нибудь знает, есть ли чистый, здоровый, путинский способ связать несвязанный метод с экземпляром и продолжить его, не называя его?
Все функции также являются дескрипторами, поэтому вы можете связать их, вызвав их метод __get__
:
bound_handler = handler.__get__(self, MyWidget)
Здесь Р. Хеттингер отлично описывает руководство для дескрипторов.
Это можно сделать с помощью 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)
.