using metaclass __call__ to replace class instance

Ksenia Marasanova ksenia.marasanova at gmail.com
Fri Sep 9 07:43:18 EDT 2005


Hi all,

I am creating some library, and want use "declarative" style in the
subclasses as much as possible, while the actual use will be more
method-like.

Just to give an impression, the library would be something like this:

class Baseclass(object):
    # lot's of code goes here...

class Basemethod(object):
    foo = None
    def get_foo(cls):
        return cls.foo
    get_foo = classmethod(get_foo)

The subclasses:

class Class(Baseclass):

    class method1(Basemethod):
        foo = "foo1"

    class method2(Basemethod):
        foo = "foo2"


And the actual use would be:

print Class.method1()
"foo1"

print Class.method2()
"foo2"

So I thought that the way to accomplish it would be using metaclass
__call__ method:

class BasemethodMeta(type):
    def __new__(cls, class_name, bases, new_attrs):
        cls = type.__new__(cls, class_name, bases, new_attrs)
        new_attrs['__metaclass__'].cls = cls
        return cls
    
    def __call__(self):
        return self.cls.get_foo()

class Basemethod(object):
    __metaclass__ = BasemethodMeta
    def get_foo(cls):
        return cls.foo
    get_foo = classmethod(get_foo)


But it doesn't work as I expected:

print Class.method1()
"foo2"
print Class.method2()
"foo2"

I understand now that because BasemethodMeta is *type* (not sure if
this is the right word)  for all Basemethod classes, it always
returnes the latest declared class... Creating dictionary and putting
all classes in it doesn't make much sense either, because
BasemethodMeta still doesn't know what is the current class that is
being called... (right?)
Now I am stuck. Can anybody show me the light?

Appreciate any help,
-- 
Ksenia



More information about the Python-list mailing list