By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,818 Members | 1,282 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,818 IT Pros & Developers. It's quick & easy.

using metaclass __call__ to replace class instance

P: n/a
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
Sep 9 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Ksenia Marasanova wrote:
class BasemethodMeta(type):
def*__new__(cls,*class_name,*bases,*new_attrs):
cls*=*type.__new__(cls,*class_name,*bases,*new_att rs)
new_attrs['__metaclass__'].cls*=*cls
return*cls

def*__call__(self):
return*self.cls.get_foo()


Though I'm not sure what you are trying to do, I fear it will get more
complicated than necessary. But you do get the desired output if
you change your metaclass to

class BasemethodMeta(type):
def __call__(cls):
# the instance of the metaclass already is a class
# so you can drop the double indirection
return cls.get_foo()

Peter
Sep 9 '05 #2

P: n/a
2005/9/9, Peter Otten <__*******@web.de>:
Ksenia Marasanova wrote:
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
returncls

def__call__(self):
returnself.cls.get_foo()


Though I'm not sure what you are trying to do, I fear it will get more
complicated than necessary. But you do get the desired output if
you change your metaclass to

class BasemethodMeta(type):
def __call__(cls):
# the instance of the metaclass already is a class
# so you can drop the double indirection
return cls.get_foo()

Peter

Man.. that's easy. Thanks a lot, Peter.

--
Ksenia
Sep 9 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.