from __future__ import * 1.12.2003

2003-12-01

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!

posted at 18:06:40    #    comment []    trackback []
December
MoTuWeThFrSaSu
1 2 3 4 5 6 7
8 91011121314
15161718192021
22232425262728
293031    
Nov Jan

Bob's Rants

XML-Image Letterimage

© 2003-2004, Bob Ippolito