Creating new types and invoking super

Discussion in 'Python' started by Guilherme Polo, Jan 23, 2008.

  1. Hello,

    Before starting, let me show some sample codes so I can explain:

    class A(object):
    def __init__(self):
    super(A, self).__init__()

    x = type("X", (A, ), {})()

    This works fine, but suppose I have several classes like A and I would
    like to create a decorator to call super. First I tried this:

    def init(func):
    def _init(inst):
    super(inst.__class__, inst).__init__()
    func(inst)

    return _init

    class A(object):
    @init
    def __init__(self): pass

    This works when I create a instance by doing A(), but I get
    "RuntimeError: maximum recursion depth exceeded" when I create a new
    type doing type("X", (A, ), {}) and then create an instance of it.
    To "solve" this problem, I changed the init function to this then:

    def init(func):
    def _init(inst):
    super(inst.__class__.__mro__[-2], inst).__init__()
    func(inst)

    return _init

    It works if A is a direct subclass of object, if it is not I have to
    adapt the index [-2].
    So, is there a better way to do this ?

    --
    -- Guilherme H. Polo Goncalves
     
    Guilherme Polo, Jan 23, 2008
    #1
    1. Advertising

  2. On Jan 23, 8:55 pm, "Guilherme Polo" <> wrote:
    > Hello,


    Hi
    [...]
    > First I tried this:
    >
    > def init(func):
    >     def _init(inst):
    >         super(inst.__class__, inst).__init__()
    >         func(inst)
    >
    >     return _init
    >
    > class A(object):
    >     @init
    >     def __init__(self): pass


    This kind of approach can't work, you need to call super(A, obj).
    super(type(obj), obj) is pointless, it defeats the whole purpose of
    the mro!

    The only way I can think of would be to create a metaclass, but I
    don't think it's worth it. super(A, obj).__init__() isn't that bad!

    --
    Arnaud
     
    Arnaud Delobelle, Jan 23, 2008
    #2
    1. Advertising

  3. 2008/1/23, Arnaud Delobelle <>:
    > On Jan 23, 8:55 pm, "Guilherme Polo" <> wrote:
    > > Hello,

    >
    > Hi
    > [...]
    > > First I tried this:
    > >
    > > def init(func):
    > > def _init(inst):
    > > super(inst.__class__, inst).__init__()
    > > func(inst)
    > >
    > > return _init
    > >
    > > class A(object):
    > > @init
    > > def __init__(self): pass

    >
    > This kind of approach can't work, you need to call super(A, obj).
    > super(type(obj), obj) is pointless, it defeats the whole purpose of
    > the mro!
    >


    Yeh, as shown in the next examples in the previous email. Using a
    decorator for that doesn't sound useful at all, was just trying
    something different ;) I will stick to the no-decorator option.

    > The only way I can think of would be to create a metaclass, but I
    > don't think it's worth it. super(A, obj).__init__() isn't that bad!
    >


    Metaclass doesn't apply here because metaclass is related to
    class-construction. This is related to instance initialization, and
    I'm creating the types as the user asks.

    > --
    > Arnaud
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >



    --
    -- Guilherme H. Polo Goncalves
     
    Guilherme Polo, Jan 23, 2008
    #3
  4. 2008/1/23, Guilherme Polo <>:
    > 2008/1/23, Arnaud Delobelle <>:
    > > On Jan 23, 8:55 pm, "Guilherme Polo" <> wrote:
    > > > Hello,

    > >
    > > Hi
    > > [...]
    > > > First I tried this:
    > > >
    > > > def init(func):
    > > > def _init(inst):
    > > > super(inst.__class__, inst).__init__()
    > > > func(inst)
    > > >
    > > > return _init
    > > >
    > > > class A(object):
    > > > @init
    > > > def __init__(self): pass

    > >
    > > This kind of approach can't work, you need to call super(A, obj).
    > > super(type(obj), obj) is pointless, it defeats the whole purpose of
    > > the mro!
    > >

    >
    > Yeh, as shown in the next examples in the previous email. Using a
    > decorator for that doesn't sound useful at all, was just trying
    > something different ;) I will stick to the no-decorator option.
    >
    > > The only way I can think of would be to create a metaclass, but I
    > > don't think it's worth it. super(A, obj).__init__() isn't that bad!
    > >

    >
    > Metaclass doesn't apply here because metaclass is related to
    > class-construction. This is related to instance initialization, and
    > I'm creating the types as the user asks.


    Oops, actually it can be done. But I am not going to stick to it, just
    did a sample here that "solves" for a not so deep structure:

    def init(func):
    def _init(cls):
    if hasattr(cls, "myclass"):
    super(cls.myclass, cls).__init__()
    else:
    super(cls.__class__, cls).__init__()
    func(cls)

    return _init

    class M(type):
    def __new__(cls, classname, bases, classdict):
    if not len(classdict):
    if 'myclass' in bases[0].__dict__:
    classdict['myclass'] = bases[0].__dict__['myclass']
    else:
    classdict['myclass'] = bases[0]


    return type.__new__(cls, classname, bases, classdict)

    class Y(object):
    __metaclass__ = M

    class X(Y):
    @init
    def __init__(self):
    print "X"

    X()
    y = type("Z", (X, ), {})
    w = type("W", (y, ), {})
    y()
    w()

    >
    > > --
    > > Arnaud
    > >
    > > --
    > > http://mail.python.org/mailman/listinfo/python-list
    > >

    >
    >
    > --
    > -- Guilherme H. Polo Goncalves
    >



    --
    -- Guilherme H. Polo Goncalves
     
    Guilherme Polo, Jan 23, 2008
    #4
  5. On Jan 23, 10:18 pm, "Guilherme Polo" <> wrote:
    > 2008/1/23, Arnaud Delobelle <>:
    >
    > > The only way I can think of would be to create a metaclass, but I
    > > don't think it's worth it.  super(A, obj).__init__() isn't that bad!

    >
    > Metaclass doesn't apply here because metaclass is related to
    > class-construction. This is related to instance initialization, and
    > I'm creating the types as the user asks.


    Not completely clear to me what you want but here is a 'proof of
    concept':

    ==========

    class callsuper(object):
    def __init__(self, f):
    self.f = f
    def __get__(self, obj, cls=None):
    def newfunc(*args, **kwargs):
    super(self.cls, obj).__init__()
    return self.f(obj, *args, **kwargs)
    return newfunc

    class Type(type):
    def __init__(self, name, bases, attrs):
    for attrname, attr in attrs.iteritems():
    if isinstance(attr, callsuper):
    attr.cls = self

    class A:
    __metaclass__ = Type
    def __init__(self):
    print "init A"

    class B(A):
    @callsuper
    def __init__(self):
    print "init B"

    ==========

    >>> b=B()

    init A
    init B
     
    Arnaud Delobelle, Jan 23, 2008
    #5
  6. 2008/1/23, Arnaud Delobelle <>:
    > On Jan 23, 10:18 pm, "Guilherme Polo" <> wrote:
    > > 2008/1/23, Arnaud Delobelle <>:
    > >
    > > > The only way I can think of would be to create a metaclass, but I
    > > > don't think it's worth it. super(A, obj).__init__() isn't that bad!

    > >
    > > Metaclass doesn't apply here because metaclass is related to
    > > class-construction. This is related to instance initialization, and
    > > I'm creating the types as the user asks.

    >
    > Not completely clear to me what you want but here is a 'proof of
    > concept':
    >
    > ==========
    >
    > class callsuper(object):
    > def __init__(self, f):
    > self.f = f
    > def __get__(self, obj, cls=None):
    > def newfunc(*args, **kwargs):
    > super(self.cls, obj).__init__()
    > return self.f(obj, *args, **kwargs)
    > return newfunc
    >
    > class Type(type):
    > def __init__(self, name, bases, attrs):
    > for attrname, attr in attrs.iteritems():
    > if isinstance(attr, callsuper):
    > attr.cls = self
    >
    > class A:
    > __metaclass__ = Type
    > def __init__(self):
    > print "init A"
    >
    > class B(A):
    > @callsuper
    > def __init__(self):
    > print "init B"
    >
    > ==========
    >
    > >>> b=B()

    > init A
    > init B
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >


    Thanks for this concept, works better than mine :)


    --
    -- Guilherme H. Polo Goncalves
     
    Guilherme Polo, Jan 24, 2008
    #6
  7. On Jan 23, 11:51 pm, Arnaud Delobelle <> wrote:
    Oops:

    >
    > class callsuper(object):
    >     def __init__(self, f):
    >         self.f = f
    >     def __get__(self, obj, cls=None):
    >         def newfunc(*args, **kwargs):
    >             super(self.cls, obj).__init__()


    Change this line to:
    getattr(super.cls, obj), self.f.__name__)()

    >             return self.f(obj, *args, **kwargs)
    >         return newfunc
     
    Arnaud Delobelle, Jan 24, 2008
    #7
  8. On Jan 24, 7:19 am, Arnaud Delobelle <> wrote:
    Oops again
    >
    > Change this line to:
    >               getattr(super.cls, obj), self.f.__name__)()


    I mean
    getattr(super(self.cls, obj), self.f.__name__)()

    --
    Arnaud
     
    Arnaud Delobelle, Jan 24, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest

    super.super.super how?

    Guest, Feb 19, 2005, in forum: Java
    Replies:
    24
    Views:
    10,791
    Darryl Pierce
    Feb 24, 2005
  2. Fernando Rodriguez

    Getting the super class via the super() function

    Fernando Rodriguez, Nov 21, 2003, in forum: Python
    Replies:
    2
    Views:
    724
    Bob Willan
    Nov 22, 2003
  3. Kerim Borchaev

    super. could there be a simpler super?

    Kerim Borchaev, Jan 15, 2004, in forum: Python
    Replies:
    4
    Views:
    478
    Michele Simionato
    Jan 15, 2004
  4. Replies:
    7
    Views:
    450
    Patricia Shanahan
    Apr 6, 2008
  5. Hugh Sasse Staff Elec Eng

    Inheriting variables, super, and "not super"?

    Hugh Sasse Staff Elec Eng, Dec 9, 2003, in forum: Ruby
    Replies:
    7
    Views:
    126
    Hugh Sasse Staff Elec Eng
    Dec 11, 2003
Loading...

Share This Page