Consider the following two classes;
class Parent(object):
def process(self, value):
retval = "Parent.result('%s')" % value
return retval
class Child(Parent):
def __init__(self):
Parent.__init__(self)
def process(self, value):
retval = "Child.result('%s')" % super(Child, self).process
(value)
return retval
So ....
foo = Child()
print foo.process('the value')
>> Child.result('Parent.result('the value')')
IS there another pattern or idiom that would accomplish this?
This seems a bit 'smelly' to me. Also seems almost the inverse of
decorators, but I am not sure decorators would be appropriate in this
case.
Any help suggestions would be appreciated.
g.
class GroupedInt(int):
def __str__(self):
old = super(GroupedInt, self).__str__()
first = old[: len(old) % 3 or 3]
if first == '-':
first = old[: 4]
parts = [first]
parts.extend(old[n : n + 3] for n in
range(len(first), len(old), 3))
return '_'.join(parts)
for n in 1, 12, 123, 1234, 12345, 123456, 1234567:
print '%s\t%s=%r\t%s=%r' % (n, GroupedInt(n), GroupedInt(n),
GroupedInt(-n), GroupedInt(-n))
1 1=1 -1=-1
12 12=12 -12=-12
123 123=123 -123=-123
1234 1_234=1234 -1_234=-1234
12345 12_345=12345 -12_345=-12345
123456 123_456=123456 -123_456=-123456
1234567 1_234_567=1234567 -1_234_567=-1234567
--Scott David Daniels
Scott....@Acm.Org
From what you have shown, there really is no _good_ reason to use
inheritance at all. Just delegate (which is the decorator pattern,
different from function decorators).
class Inner(object):
def process(self, value):
retval = "Parent.result('%s')" % value
return retval
class Outer(object):
def __init__(self, inner):
self._inner = inner
def process(self, value):
retval = "Outer.result('%s')" % self._inner.process(value)
return retval
This is a silly example, but if you can get the same thing done
without creating a direct dependence between classes then don't. You
will have to construct outer and pass it inner somewhere. If that is a
problem, then just make a factory. In python I implement factories as
just functions most of the time.
The above also encourages reuse. Now you have a decorator that could
be used anywhere.
Matt
Delete this and the parent __init__ is called directly.
>
> def process(self, value):
> retval = "Child.result('%s')" % super(Child, self).process
> (value)
> return retval
super() was designed for multiple inheritance. The only reason I know
to use it with single inheritance it to save a
global-search-and-replace_with_confirmation if you change the name of
the parent or change parents. Unless I really anticipated such
contigencies, I would probably write Parent.process(self, value).
tjr
> super() was designed for multiple inheritance.
Surely you mean that super() was designed for *inheritance*, multiple or
singular? Working with single inheritance is part of the design, not an
accident of implementation.
> The only reason I know
> to use it with single inheritance it to save a
> global-search-and-replace_with_confirmation if you change the name of
> the parent or change parents.
How about these reasons?
(1) If you're subclassing something you didn't write, you might not know
whether it uses multiple or single inheritance.
(2) Even if you do know, you shouldn't care what the implementation of
the parent is. Using super() allows you to be agnostic about the
implementation, while calling Parent.method() directly ties you to a
specific implementation.
(3) Your callers may want to inherit from your class, and if you fail to
use super, you are condemning them to potentially buggy code if they use
multiple inheritance.
(4) Using super() is no harder than avoiding super(). It takes a few
extra characters to type, at worst:
super(MyClass, self).method(args)
Parent.method(self, args)
--
Steven
I think I would split out the calculation into two methods in this case:
class Parent(object):
def process_essential(self,value):
retval = "Parent.result('%s')" % value
return retval
def processs(self,value):
return process_essential(value)
class Child(Parent):
def process(self,value):
retval = "Child.result('%s')" % process_essential(value)
return retval
--
André Engels, andre...@gmail.com
I see nothing wrong with it, although if it is possible and convenient
to rename the base class method, as Andre Engels suggests, then that's
usually how I'd do it.
Sometimes it's not convenient to choose a different name for the base
class method, such as when you have several subclasses, most of which
don't override the method, but a few do. In that case I'd do it same
way as you did.
One thing that does smell is your use of both old-style base class
access (Parent.__init__(self)) and newer-style (super
(Child,self).process()) in the same class. Pick one method and stick
with it.
Carl Banks
class Parent(object):
def process(self, value):
retval = "%s.result('%s')" % (self.__class__.__name__, value)
return retval
class Child(Parent):
def __init__(self):
Parent.__init__(self)
foo = Child()
print foo.process('the value')
>>> Child.result('the value'')
Of course you cannot see the inheritance in the result, but I'm assuming you wanted only the instance class to be displayed.
Jean-Michel