[Tutor] is this code dangerous?

Gonçalo Rodrigues op73418@mail.telepac.pt
Wed Jan 8 10:58:01 2003


----- Original Message -----
From: "Alfred Milgrom" <fredm@smartypantsco.com>
To: <tutor@python.org>
Sent: Wednesday, January 08, 2003 1:14 PM
Subject: [Tutor] is this code dangerous?


> Hi:
>
> Can someone please tell me the best way to override class methods for
> specific instances?
>
> I want to have a general class, such as Person, with general methods. Some
> of the instances of the Person class may have different methods, and I
want
> to be able to override the base method (such as the speak method for the
> cranky person in the example below).
>
> Do I need to define a new class for each instance where there is a
> different method? Is there overhead associated with having a large number
> of classes?
>

Using the example you give below you can also do:

>>> class Person:
...  def __init__(self, name):
...   self.name = name
...  def speak(self):
...   print "%s says: my name is %s" % (self.name, self.name)
...
>>> Person
<class __main__.Person at 0x0110A970>
>>> cranky = Person('someone else')
>>> def crankyspeak(self):
...  print "%s says: I don't tell anyone my name" % (self.name)
...
>>> cranky.speak = crankyspeak

But you have to notice though that speak is not a method but a plain
function object: self is not automatically passed, e.g.

>>> cranky.speak()
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
TypeError: crankyspeak() takes exactly 1 argument (0 given)
>>> cranky.speak(cranky)
someone else says: I don't tell anyone my name

There are ways of course to override this - e.g. using something like the
template pattern. You could code something like

class Person:
    <whatever>

    def speak(self):
        __speak = self.et('my_speak')
        if __speak is not None:
            __speak(self)
        else:
            print "%s says: my name is %s" % (self.name, self.name)

This allows the user to just add a my_speak method to the instance and the
speak method just looks for it first.

I am sure there are other (and better) ways to do this, but it's an initial
step. And do not worry about overhead unless you really have to e.g. your
analysis has proved that you do need to worry - your program is not fast
enough to meet the requirements - and that this place in the program is one
of the bottlenecks.


> Is the following code dangerous? (Obviously I could change the name of the
> cranky class to crankyperson, or something like that, and have a different
> class for each instance). What is the best way to handle this?
>

What do you mean by dangerous?

> ************************
>
> class Person:
>      def __init__(self, name):
>          self.name = name
>
>      def speak(self):
>          print "%s says: my name is %s" % (self.name, self.name)
>
> hobbit = Person('Bilbo Baggins')
>
> class cranky(Person):
>      def speak(self):
>          print "%s says: I don't tell anyone my name" % (self.name)
>
> cranky = cranky('someone else')
>
> hobbit.speak()
> cranky.speak()
>
> ************************
>
> Thanks in advance,
> Fred Milgrom
>

With my best regards,
G. Rodrigues