Lassen Sie uns sagen, dass wir eine Metaklasse CallableWrappingMeta
haben, die den Körper einer neuen Klasse geht, ihre Methoden mit einer Klasse Verpackung, InstanceMethodWrapper
.aufrufbar als 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!'
Unser Dummy-Wrapper druckt nur die Argumente, wie sie hereinkommen Aber Sie Ich bemerke etwas Auffälliges: Die Methode wird nicht an den Instanz-Objekt-Empfänger übergeben, denn obwohl InstanceMethodWrapper
aufrufbar ist, wird sie nicht als eine Funktion für die Umwandlung in eine Instanzmethode während der Klassenerstellung behandelt (nach unserer Metaklasse) damit gemacht).
Eine mögliche Lösung besteht darin, einen Decorator anstelle einer Klasse zu verwenden, um die Methoden zu umbrechen - diese Funktion wird zu einer Instanzmethode. Aber in der realen Welt ist InstanceMethodWrapper
viel komplexer: Es bietet eine API und veröffentlicht Methodenaufrufereignisse. Eine Klasse ist bequemer (und leistungsfähiger, nicht dass das viel ausmacht).
Ich versuchte auch einige Sackgassen. Subclassing types.MethodType
und types.UnboundMethodType
gingen nirgendwohin. Eine kleine Introspektion, und es scheint, dass sie von type
abweichen. Also habe ich versucht, beides als Metaklasse zu benutzen, aber auch kein Glück. Es kann sein, dass sie spezielle Anforderungen als Metaklasse haben, aber es scheint, dass wir uns an diesem Punkt in undokumentiertem Territorium befinden.
Irgendwelche Ideen?
Können Sie bitte mehr erklären? Ich habe Probleme zu verstehen, was du zu tun versuchst. – Unknown