using metaclass __call__ to replace class instance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ksenia Marasanova

    #1

    using metaclass __call__ to replace class instance

    Hi all,

    I am creating some library, and want use "declarativ e" 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(objec t):
    # lot's of code goes here...

    class Basemethod(obje ct):
    foo = None
    def get_foo(cls):
    return cls.foo
    get_foo = classmethod(get _foo)

    The subclasses:

    class Class(Baseclass ):

    class method1(Basemet hod):
    foo = "foo1"

    class method2(Basemet hod):
    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__(cl s, class_name, bases, new_attrs)
    new_attrs['__metaclass__'].cls = cls
    return cls

    def __call__(self):
    return self.cls.get_fo o()

    class Basemethod(obje ct):
    __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
  • Peter Otten

    #2
    Re: using metaclass __call__ to replace class instance

    Ksenia Marasanova wrote:
    [color=blue]
    > class BasemethodMeta( type):
    > def __new__(cls, class_name, bases, new_attrs):
    > cls = type.__new__(cl s, class_name, bases, new_attrs)
    > new_attrs['__metaclass__'].cls = cls
    > return cls
    >
    > def __call__(self):
    > return self.cls.get_fo o()[/color]

    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


    Comment

    • Ksenia Marasanova

      #3
      Re: using metaclass __call__ to replace class instance

      2005/9/9, Peter Otten <__peter__@web. de>:[color=blue]
      > Ksenia Marasanova wrote:
      > [color=green]
      > > class BasemethodMeta( type):
      > > def__new__(cls, class_name,base s,new_attrs):
      > > cls=type.__new_ _(cls,class_nam e,bases,new_att rs)
      > > new_attrs['__metaclass__'].cls=cls
      > > returncls
      > >
      > > def__call__(sel f):
      > > returnself.cls. get_foo()[/color]
      >
      > 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
      > [/color]


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

      --
      Ksenia

      Comment

      Working...