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

M

metal

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?
 
C

Chris Rebert

Consider the following:
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
 
D

Dave Angel

metal said:
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
 
M

metal

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()
 
M

metal

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']
 
B

Bruno Desthuilliers

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.
 
B

Bruno Desthuilliers

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).
 
M

metal

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
 
B

Bruno Desthuilliers

metal a écrit :
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?

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).
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top