If a class Child inherits from Parent, how to implementChild.some_method if Parent.some_method() ret

Discussion in 'Python' started by metal, Oct 29, 2009.

  1. metal

    metal Guest

    Consider the following:

    ########################################
    class Parent:
    def some_method(self):
    return Parent(...)
    class Child:
    def some_method(self):
    ...
    return Parent.some_method(self)
    ########################################

    Or Simply:

    ########################################
    class Parent:
    def some_method(self):
    return Parent(...)
    class Child:
    pass
    ########################################

    Child().some_method() returns a Parent instance.

    We can rewrite Parent like this to avoid that

    ########################################
    class Parent:
    def some_method(self):
    return self.__class__(...)
    class Child:
    def some_method(self):
    ...
    return Parent.some_method(self)
    ########################################

    But this style makes code full with ugly self.__class__

    Any standard/pythonic way out there?
    metal, Oct 29, 2009
    #1
    1. Advertising

  2. metal

    Chris Rebert Guest

    On Thu, Oct 29, 2009 at 3:45 PM, metal <> wrote:
    > Consider the following:

    <snip>
    > class Parent:
    >        def some_method(self):
    >                return Parent(...)
    > class Child:
    >        pass
    > ########################################
    >
    > Child().some_method() returns a Parent instance.
    >
    > We can rewrite Parent like this to avoid that
    >
    > ########################################
    > class Parent:
    >        def some_method(self):
    >                return self.__class__(...)
    > class Child:
    >        def some_method(self):
    >                ...
    >                return Parent.some_method(self)
    > ########################################
    >
    > But this style makes code full with ugly  self.__class__
    >
    > Any standard/pythonic way out there?


    That pretty much is the standard way AFAIK. A few underscores aren't
    all that bad in the grand scheme of things.

    Cheers,
    Chris
    --
    http://blog.rebertia.com
    Chris Rebert, Oct 29, 2009
    #2
    1. Advertising

  3. metal

    Dave Angel Guest

    Re: If a class Child inherits from Parent,how to implement Child.some_methodif Parent.some_method() returns Parent instance ?

    metal wrote:
    > Consider the following:
    >
    > ########################################
    > class Parent:
    > def some_method(self):
    > return Parent(...)
    > class Child:
    > def some_method(self):
    > ...
    > return Parent.some_method(self)
    > ########################################
    >
    > Or Simply:
    >
    > ########################################
    > class Parent:
    > def some_method(self):
    > return Parent(...)
    > class Child:
    > pass
    > ########################################
    >
    > Child().some_method() returns a Parent instance.
    >
    > We can rewrite Parent like this to avoid that
    >
    > ########################################
    > class Parent:
    > def some_method(self):
    > return self.__class__(...)
    > class Child:
    > def some_method(self):
    > ...
    > return Parent.some_method(self)
    > ########################################
    >
    > But this style makes code full with ugly self.__class__
    >
    > Any standard/pythonic way out there?
    >
    >
    >

    You need to do a few things here.
    1) tell us what version of Python you're targeting, and whether these
    are old-style or new-style classes you're trying to define.

    2) Actually show the class declaration completely. Currently you don't
    show the (object) or the (Parent) base class declarations.

    3) Explain what the desired goal is. Using a phrase like "rewrite
    Parent like this to avoid that" implies that I already know what
    particular "that" has you bothered.

    4) If you post multiple similar code blocks, label them somehow, so we
    have a way to refer to them unambiguously.

    With my present guesses, the definition of some_method() in the third
    declaration of Child would seem to be redundant.

    DaveA
    Dave Angel, Oct 29, 2009
    #3
  4. metal

    metal Guest

    The actual situation is I'm coding with a immuable set-like datatype
    XSet which supports XSet(['al']) & XSet(['ah'] = XSet(['ax'] if I
    declare ax is consists of al and ah

    "That" means I can't explian it very well 'cause my english...

    Now I try to make some mess like this...I know it's not good to wrap
    all methods...I just try to make code looks good

    class MyMeta(type):
    def __init__(cls, name, bases, namespace):
    type.__init__(cls, name, bases, namespace) # needed?
    cls.wrap_methods()
    def methods(cls):
    return [k for k, v in cls.__dict__.items() if callable(v)]
    def wrap_methods(cls):
    for k in cls.methods():
    f = cls.__dict__[k]
    def g(self, *v, **k):
    rv = f(self, *v, **k)
    if rv.__class__ is cls:
    rv = self.__class__()
    rv.__dict__.update(self.__dict__)
    return rv
    setattr(cls, k, g)

    class Parent(object):
    __metaclass__ = MyMeta # I prefer class decorator, but I'm using
    Py2.5
    def some_method(self):
    return Parent()

    class Child(Parent):
    pass

    print Child().some_method()
    metal, Oct 30, 2009
    #4
  5. metal

    metal Guest

    On 10ÔÂ30ÈÕ, ÉÏÎç8ʱ03·Ö, metal <> wrote:
    > The actual situation is I'm coding with a immuable set-like datatype
    > XSet which supports XSet(['al']) & XSet(['ah'] = XSet(['ax'] if I
    > declare ax is consists of al and ah
    >


    A typo, XSet(['al']) | XSet(['ah'] = XSet(['ax']
    metal, Oct 30, 2009
    #5
  6. Re: If a class Child inherits from Parent, how to implement Child.some_methodif Parent.some_method() returns Parent instance ?

    metal a écrit :
    > The actual situation is I'm coding with a immuable set-like datatype
    > XSet which supports XSet(['al']) & XSet(['ah'] = XSet(['ax']


    I assume it was '==', not '='

    > if I
    > declare ax is consists of al and ah
    >
    > "That" means I can't explian it very well 'cause my english...
    >
    > Now I try to make some mess like this...I know it's not good to wrap
    > all methods...I just try to make code looks good
    >
    > class MyMeta(type):
    > def __init__(cls, name, bases, namespace):
    > type.__init__(cls, name, bases, namespace) # needed?
    > cls.wrap_methods()
    > def methods(cls):
    > return [k for k, v in cls.__dict__.items() if callable(v)]


    All callables are not functions or methods... The inspect module might
    help you here.

    > def wrap_methods(cls):
    > for k in cls.methods():
    > f = cls.__dict__[k]



    Just for the record, you wouldn't have to do this lookup if .methods
    returned the actual objects instead of their names) if callable(v)).


    > def g(self, *v, **k):
    > rv = f(self, *v, **k)
    > if rv.__class__ is cls:
    > rv = self.__class__()
    > rv.__dict__.update(self.__dict__)
    > return rv
    > setattr(cls, k, g)




    If you do have control over the whole class hierarchy, just write the
    base class so the alternate constructors return instances of the
    appropriate class. Else, manually wrapping the relevant methods would be
    a better solution IMHO. I'm not for premature optimization, but remember
    that method lookup and function call are two costly operations in
    Python, so better not adding too much overhead.
    Bruno Desthuilliers, Oct 30, 2009
    #6
  7. Re: If a class Child inherits from Parent, how to implement Child.some_methodif Parent.some_method() returns Parent instance ?

    metal a écrit :
    > Consider the following:
    >

    (snip)
    > class Parent:
    > def some_method(self):
    > return Parent(...)
    > class Child:
    > pass
    >
    > Child().some_method() returns a Parent instance.


    It actually raises an AttributeError. You forgot to make Child inherit
    from Parent.


    > We can rewrite Parent like this to avoid that
    >
    > ########################################
    > class Parent:
    > def some_method(self):
    > return self.__class__(...)
    > class Child:
    > def some_method(self):
    > ...
    > return Parent.some_method(self)
    > ########################################
    >
    > But this style makes code full with ugly self.__class__
    >
    > Any standard/pythonic way out there?


    Others already gave you the appropriate answer (if appliable, of
    course), which is to make some_method a classmethod, or, if some_method
    needs to stay an instancemethod, to factor out the creation of a new
    instance to a classmethod.

    Now if it's the self.__class__ that hurts you, you can as well replace
    it with type(self) - assuming you make Parent a new-style class (which
    FWIW is the sensible thing to do anyway).
    Bruno Desthuilliers, Oct 30, 2009
    #7
  8. metal

    metal Guest

    On 10月30æ—¥, 下åˆ4æ—¶44分, Bruno Desthuilliers <bruno.
    > wrote:
    > metal a écrit :
    >
    > > The actual situation is I'm coding with a immuable set-like datatype
    > > XSet which supports XSet(['al']) & XSet(['ah'] = XSet(['ax']

    >
    > I assume it was '==', not '='
    >
    > > if I
    > > declare ax is consists of al and ah

    >
    > > "That" means I can't explian it very well 'cause my english...

    >
    > > Now I try to make some mess like this...I know it's not good to wrap
    > > all methods...I just try to make code looks good

    >
    > > class MyMeta(type):
    > >     def __init__(cls, name, bases, namespace):
    > >         type.__init__(cls, name, bases, namespace) # needed?
    > >         cls.wrap_methods()
    > >     def methods(cls):
    > >         return [k for k, v in cls.__dict__.items() if callable(v)]

    >
    > All callables are not functions or methods... The inspect module might
    > help you here.
    >
    > >     def wrap_methods(cls):
    > >         for k in cls.methods():
    > >             f = cls.__dict__[k]

    >
    > Just for the record, you wouldn't have to do this lookup if .methods
    > returned the actual objects instead of their names) if callable(v)).
    >
    > >             def g(self, *v, **k):
    > >                 rv = f(self, *v, **k)
    > >                 if rv.__class__ is cls:
    > >                     rv = self.__class__()
    > >                     rv.__dict__.update(self.__dict__)
    > >                 return rv
    > >             setattr(cls, k, g)

    >
    > If you do have control over the whole class hierarchy, just write the
    > base class so the alternate constructors return instances of the
    > appropriate class. Else, manually wrapping the relevant methods would be
    > a better solution IMHO. I'm not for premature optimization, but remember
    > that method lookup and function call are two costly operations in
    > Python, so better not adding too much overhead.


    All code are just POCs. == or = doesn't matter :)

    Sure I know .methods() can return actual objects if ONLY iteration,
    but how to overwrite it?

    type(self) in new-style class looks a little better, thanks for the
    idea
    metal, Oct 30, 2009
    #8
  9. Re: If a class Child inherits from Parent, how to implement Child.some_methodif Parent.some_method() returns Parent instance ?

    metal a écrit :
    > On 10月30æ—¥, 下åˆ4æ—¶44分, Bruno Desthuilliers <bruno.
    > > wrote:
    >> metal a écrit :

    (snip)
    >>> def methods(cls):
    >>> return [k for k, v in cls.__dict__.items() if callable(v)]

    >> All callables are not functions or methods... The inspect module might
    >> help you here.
    >>
    >>> def wrap_methods(cls):
    >>> for k in cls.methods():
    >>> f = cls.__dict__[k]

    >> Just for the record, you wouldn't have to do this lookup if .methods
    >> returned the actual objects instead of their names)


    >
    > Sure I know .methods() can return actual objects if ONLY iteration,
    > but how to overwrite it?


    Ahem... <cough> yes, right, you do need the key too. But you still can
    avoid the extra dict lookup : just return both the key and object !-)

    > type(self) in new-style class looks a little better, thanks for the
    > idea


    FWIW and as a general rule, __special_names__ are mostly implementation
    support for operator or operator-like generic functions, and not
    intented for direct access (except when you really need it of course).
    Bruno Desthuilliers, Oct 30, 2009
    #9
    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. Alex Nitulescu
    Replies:
    0
    Views:
    339
    Alex Nitulescu
    Feb 22, 2005
  2. Karl Heinz Buchegger

    Re: delete this; return ret;

    Karl Heinz Buchegger, Jun 24, 2003, in forum: C++
    Replies:
    0
    Views:
    828
    Karl Heinz Buchegger
    Jun 24, 2003
  3. ton
    Replies:
    1
    Views:
    998
    Teemu Keiski
    Jun 24, 2007
  4. Noel Dolan
    Replies:
    0
    Views:
    214
    Noel Dolan
    Jul 18, 2004
  5. Bitswapper
    Replies:
    5
    Views:
    116
    Prasad, Ramit
    Aug 27, 2013
Loading...

Share This Page