Question about metaclass

Ian Kelly ian.g.kelly at gmail.com
Wed Nov 2 00:40:17 EDT 2011


On Tue, Nov 1, 2011 at 10:02 PM, Makoto Kuwata <kwa at kuwata-lab.com> wrote:
> I tried the following code which converts instance mthods into
> static method automatically, but I don't get result what I want.
> (python 2.5.5)
>
>    import sys
>    from types import FunctionType
>
>    class MetaClass(type):
>        def __init__(cls, name, bases, dct):
>            ## converts instance methods to static methods automatically
>            for k in dct.keys():
>                v = dct[k]
>                if isinstance(v, FunctionType):
>                    dct[k] = staticmethod(v)
>                    print("*** debug: dct[%r] = %r" % (k, dct[k]))

If you want to customize the dict you need to do it in __new__, not
__init__.  By the time __init__ is called, the class has already been
created.

class MetaClass(type):
    def __new__(mcs, name, bases, dict):
        for k, v in dict.items():
            if isinstance(v, FunctionType):
                dict[k] = staticmethod(v)
        return type.__new__(mcs, name, bases, dict)

If you were using a more recent Python version, I would suggest using
a class decorator instead of a metaclass.  You can still do this in
Python 2.5, but the syntax will be more awkward.

# Python 2.6+
def FuncGroup(class_):
    for k, v in class_.__dict__.items():
        if isinstance(v, FunctionType):
            setattr(class_, k, staticmethod(v))
    return class_

@FuncGroup
class Greeting(object):
    def hello():
        print("Hello!")

# Python 2.5
class Greeting(object):
    def hello():
        print("Hello!")
Greeting = FuncGroup(Greeting)

Cheers,
Ian



More information about the Python-list mailing list