«
meta/instance method descriptor
»
This is odd, but I ran into a situation where I wanted to have a method be callable from both the class (as a metamethod) and the instance (as a normal instance method). The only decent way I could think of was to use a descriptor, here's an example:
class metainstancemethod(object): def __init__(self, instancemethod, metamethod): self.metamethod = metamethod self.instancemethod = instancemethod def __get__(self, frominstance, fromclass): if frominstance is None: return self.metamethod.__get__(fromclass, fromclass.__metaclass__) return self.instancemethod.__get__(frominstance, fromclass) class Meta(type): def magic(self): print self, "metamagic" class Minor(object): __metaclass__ = Meta def magic(self): print self, "magic" magic = metainstancemethod(magic, Meta.magic)
Updates:
Phillip J. Eby came up with a better way to do this for PyProtocols. Basically, the descriptor goes on the metaclass rather than the class, which is less work and requires less magic. Check the comments (or PyProtocols) for his implementation. Thanks!