Re: can a subclass method determine if called by superclass?

2012-01-05 Thread Jean-Michel Pichavant

Peter wrote:

Situation: I am subclassing a class which has methods that call other
class methods (and without reading the code of the superclass I am
discovering these by trial and error as I build the subclass - this is
probably why I may have approached the problem from the wrong
viewpoint :-)).

Problem: when overriding one of these indirectly called superclass
methods I would like to take differing actions (in the subclass
instance) depending on whether it is the superclass or the subclass
instance performing the call.

Question: Is there any way to determine in a method whether it is
being called by the superclass or by a method of the subclass
instance?

Now I suspect that what I am doing is actually very muddy thinking :-)
and I don't want to attempt to explain why I am approaching the design
this way as an explanation would require too much work - I will
consider an alternative inheritance approach while waiting an answer,
but the answer to the question interested me (even if I do a redesign
and come up with a more elegant approach to the problem).

Thanks
Peter
  

As you suspected, this is probably the wrong approach.

However since you asked for a solution anyway :o)

class Parent(object):
 def foo(self):
   # implementation by subclasses is still REQUIRED
   if self.__class__ is Parent:
  raise NotImplementedError()
   # common code for all foo methods
   print calling foo

class Child(Parent):
 def foo(self):
   # You can still call the virtual method which contains some code 
   Parent.foo(self)

   # here the custom code


p = Parent()
c = Child()


c.foo()
p.foo()

Note that this is not the best approach, still acceptable because there 
is no code specific to a subclass in the base class.


JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: can a subclass method determine if called by superclass?

2012-01-05 Thread Jean-Michel Pichavant

Jean-Michel Pichavant wrote:

Peter wrote:

Situation: I am subclassing a class which has methods that call other
class methods (and without reading the code of the superclass I am
discovering these by trial and error as I build the subclass - this is
probably why I may have approached the problem from the wrong
viewpoint :-)).

Problem: when overriding one of these indirectly called superclass
methods I would like to take differing actions (in the subclass
instance) depending on whether it is the superclass or the subclass
instance performing the call.

Question: Is there any way to determine in a method whether it is
being called by the superclass or by a method of the subclass
instance?

Now I suspect that what I am doing is actually very muddy thinking :-)
and I don't want to attempt to explain why I am approaching the design
this way as an explanation would require too much work - I will
consider an alternative inheritance approach while waiting an answer,
but the answer to the question interested me (even if I do a redesign
and come up with a more elegant approach to the problem).

Thanks
Peter
  

As you suspected, this is probably the wrong approach.

However since you asked for a solution anyway :o)

class Parent(object):
 def foo(self):
   # implementation by subclasses is still REQUIRED
   if self.__class__ is Parent:
  raise NotImplementedError()
   # common code for all foo methods
   print calling foo

class Child(Parent):
 def foo(self):
   # You can still call the virtual method which contains some code
Parent.foo(self)

   # here the custom code


p = Parent()
c = Child()


c.foo()
p.foo()

Note that this is not the best approach, still acceptable because 
there is no code specific to a subclass in the base class.


JM
I just realized I didn't addressed the problem you described, sorry, 
just ignore my mail.


JM
--
http://mail.python.org/mailman/listinfo/python-list


can a subclass method determine if called by superclass?

2012-01-04 Thread Peter
Situation: I am subclassing a class which has methods that call other
class methods (and without reading the code of the superclass I am
discovering these by trial and error as I build the subclass - this is
probably why I may have approached the problem from the wrong
viewpoint :-)).

Problem: when overriding one of these indirectly called superclass
methods I would like to take differing actions (in the subclass
instance) depending on whether it is the superclass or the subclass
instance performing the call.

Question: Is there any way to determine in a method whether it is
being called by the superclass or by a method of the subclass
instance?

Now I suspect that what I am doing is actually very muddy thinking :-)
and I don't want to attempt to explain why I am approaching the design
this way as an explanation would require too much work - I will
consider an alternative inheritance approach while waiting an answer,
but the answer to the question interested me (even if I do a redesign
and come up with a more elegant approach to the problem).

Thanks
Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: can a subclass method determine if called by superclass?

2012-01-04 Thread Ian Kelly
On Wed, Jan 4, 2012 at 3:42 PM, Peter peter.milli...@gmail.com wrote:
 Situation: I am subclassing a class which has methods that call other
 class methods (and without reading the code of the superclass I am
 discovering these by trial and error as I build the subclass - this is
 probably why I may have approached the problem from the wrong
 viewpoint :-)).

 Problem: when overriding one of these indirectly called superclass
 methods I would like to take differing actions (in the subclass
 instance) depending on whether it is the superclass or the subclass
 instance performing the call.

 Question: Is there any way to determine in a method whether it is
 being called by the superclass or by a method of the subclass
 instance?

Well, you could get the previous stack level using
traceback.extract_stack() and check the filename.  But it sounds like
what you actually have are two different methods -- one that is used
by the superclass, and one that only the subclass knows about and
uses.  Why not implement it as such?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: can a subclass method determine if called by superclass?

2012-01-04 Thread Peter
On Jan 5, 10:09 am, Ian Kelly ian.g.ke...@gmail.com wrote:


 Well, you could get the previous stack level using
 traceback.extract_stack() and check the filename.  But it sounds like
 what you actually have are two different methods -- one that is used
 by the superclass, and one that only the subclass knows about and
 uses.  Why not implement it as such?

Thanks Ian - that is one possibility.

I am trying to create a subclass with slightly different functionality
and use it with an existing code base i.e. there is already one or
more modules that instantiate the current superclass and I want to
just drop in this new class to replace it with no ripples up the line
(so to speak). The new class implements some interface changes that
can safely be hidden from the rest of the application.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: can a subclass method determine if called by superclass?

2012-01-04 Thread Steven D'Aprano
On Wed, 04 Jan 2012 15:37:55 -0800, Peter wrote:

 I am trying to create a subclass with slightly different functionality
 and use it with an existing code base i.e. there is already one or
 more modules that instantiate the current superclass and I want to
 just drop in this new class to replace it with no ripples up the line
 (so to speak). The new class implements some interface changes that
 can safely be hidden from the rest of the application.

This is *exactly* the idea behind subclassing. I don't understand your 
problem, can you explain more?

If you want to change behaviour of an object, you subclass it, then 
override or overload the methods you want to change. You certainly 
shouldn't be changing the superclass to recognise when it is being called 
from a subclass! That's completely the wrong approach -- you should put 
all the new behaviour in the new class.


# WRONG! Don't do this.

class Parent(object):
def method(self, arg):
if type(self) is not Parent:
# Must be a subclass.
print(Called from a subclass. But which one?)
print(Doing method stuff.)

class Child(Parent):
pass


# RIGHT! Do this instead.

class Parent(object):
def method(self, arg):
print(Doing method stuff.)

class Child(Parent):
def method(self, arg):
# Overload an existing method.
print(Called from Child subclass.)
super().method(arg)  # Python 3 only
# Python 2 use: super(Child, self).method(arg)


If method() returns a result, you can capture the result of calling the 
superclass method and then modify it as needed. Or you can override the 
method completely, and not call the parent method() at all.

Now you can use Child() anywhere that you can use Parent and the caller 
shouldn't even notice. Or at least that is the idea behind subclassing, 
although it is possible to break it. You will be okay if the caller uses 
duck-typing, or isinstance checks, but not if they do exact type checks 
(which is almost always the wrong thing to do).

c = Child()

# Duck-typing works:
hasattr(c, 'method')  # returns True

# So do isinstance checks:
isinstance(c, Parent)  # returns True

# but this doesn't and defeats the purpose of having subclasses:
type(c) is Parent  # returns False, you shouldn't do this!


If the caller does do exact type checks, then almost certainly it should 
be considered a bug in their code and they should be beaten with a clue-
bat and told to use isinstance (good) or duck-typing (better still).


If I have misunderstood your problem, can you give a concrete (but 
simple) example of what you are trying to do?



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list