Допустим, у нас есть метакласса CallableWrappingMeta
который ходит тело нового класса, обернув его методы с классом, InstanceMethodWrapper
:., вызываемый как instancemethod?
import types
class CallableWrappingMeta(type):
def __new__(mcls, name, bases, cls_dict):
for k, v in cls_dict.iteritems():
if isinstance(v, types.FunctionType):
cls_dict[k] = InstanceMethodWrapper(v)
return type.__new__(mcls, name, bases, cls_dict)
class InstanceMethodWrapper(object):
def __init__(self, method):
self.method = method
def __call__(self, *args, **kw):
print "InstanceMethodWrapper.__call__(%s, *%r, **%r)" % (self, args, kw)
return self.method(*args, **kw)
class Bar(object):
__metaclass__ = CallableWrappingMeta
def __init__(self):
print 'bar!'
Наш манекен обертка просто печатает аргументы, как они приходят в Но Отметьте что-то заметное: метод не передается получателем экземпляра объекта, потому что хотя InstanceMethodWrapper
вызываем, он не рассматривается как функция с целью преобразования в метод экземпляра во время создания класса (после того, как наш метакласс сделано с ним).
Потенциальным решением является использование декоратора вместо класса для обертывания методов - эта функция станет методом экземпляра. Но в реальном мире InstanceMethodWrapper
намного сложнее: он предоставляет API и публикует события вызова метода. Класс более удобен (и более результативен, но это не так важно).
Я также пробовал некоторые тупики. Подклассификация types.MethodType
и types.UnboundMethodType
не шла никуда. Немного интроспекции, и кажется, что они делятся с type
. Поэтому я попытался использовать как метакласс, но и не повезло. Может быть, у них есть особые требования в качестве метакласса, но, похоже, на данный момент мы находимся на недокументированной территории.
Любые идеи?
Не могли бы вы объяснить больше? Мне трудно понять, что вы пытаетесь сделать. – Unknown