overriding methods - two questions

Peter Otten __peter__ at web.de
Sat Nov 17 04:51:12 EST 2007


Donn Ingle wrote:

>> I am curious as to why you want to go through such contortions.  What
>> do you gain. 
> for obj in list:
>  if obj has a foo() method: 
>   a = something
>   b = figureitout ( )
>   object.foo ( a, b )
> 
> I am accepting objects of any class on a stack. Depending on their nature I
> want to call certain methods within them. They can provide these methods or
> not. 
> 
>> What happens, for example, if a subclass of Judy is 
>> passed in that does not override foo?  Should foo be called in that
>> case or not?
> No.

Hmm, you are missing the point of inheritance. Behaviour not
meant to be shared by all subclasses should not be implemented in
the base class, i. e. either Sam should not inherit from Child or Child
should not implement foo(). 

However, here is another hack to hide an inherited method:

>>> class Child(object):
...     def foo(self): print "Child's foo"
...     def __str__(self): return self.__class__.__name__
... 
>>> class Sam(Child):
...     @property
...     def foo(self): raise AttributeError
... 
>>> class Judy(Child):
...     def foo(self): print "Judy's foo"
... 
>>> for item in [Sam(), Judy()]:
...     try:
...             foo = item.foo
...     except AttributeError:
...             print "no foo for", item
...     else:
...             foo()
... 
no foo for Sam
Judy's foo

If you find try ... except too verbose -- it works with hasattr(), too.

> Bruno has given me a good solution:
> 
> for obj in list:
>  if 'foo' in obj.__class__.__dict__:
>   etc.
> 
> Although I am concerned that it's a loop ('in') and so may be slower
> than some other way to detect foo().

__dict__ is a dictionary (who would have thought), the "in" operator
therefore does not trigger a loop and is very fast.

Peter



More information about the Python-list mailing list