[Tutor] Adding a bound method dynamically (newbie)

Kirby Urner urnerk@qwest.net
Fri, 23 Nov 2001 08:46:17 -0800


Hi karhik --


>t.func2(). I don't want to do t.func2(t) and thereby giving access to the
>instance.

You can poke your new bound method into the class definition,
not into the instance.  For example:

  >>> class Test2:

      def __init__(self):
         self.name="Python"
         self.age=100
      def func(self):
         print 'func'


  >>> t = Test2()
  >>> t.salary = 12000
  >>> def taxes(self):
         return self.salary/10.0  # note 'self'

  >>> Test2.taxes = taxes  # add method to class
  >>> dir(t)               # shows up in instance...
  ['__doc__', '__init__', '__module__', 'age', 'func', 'name',
  'salary', 'taxes']

  >>> t.taxes
  <bound method Test.taxes of <__main__.Test object at 0x0121F710>>

  >>> t.taxes              # ...as a new bound method...

  >>> t.taxes()            # and is usable with no args
  1200.0

If you don't want the bound method to persist after using it,
delete it:

  >>> del(Test2.taxes)

  >>> dir(t)
  ['__doc__', '__init__', '__module__', 'age', 'func', 'name',
  'salary']

Inserting a method into the class makes sense, because that's
the place in memory where methods get defined.  The instances
are just little dictionaries with pointers to all the
functionality in the class.

>Another question:
>
>when i did a dir(<class-name>) => it gave a list of the methods
>associated with the class irrespective of wether it is a bound
>method or not.
>
>when i did a dir(<instance of class>) => it gave a list of the
>instance attributes associated with the class Now i might have
>methods which are bound so s'd'nt dir(<instance>) indicate that
>those bound methods can also be invoked on the instance?
>Basically i w'd like to know as to why dir() behaves that way.

Note that if you poke your new methods into the class, not the
instance, then you'll have it listed in the dir(instance) as
well as the dir(class).

If you want hooks to more class infrastructure, there's a new
universal object in Python 2.2 that you're free to inherit from,
called object (lowercase):

  >>> class Test(object):

       def __init__(self):
           self.name="Python"
           self.age=100
       def func(self):
           print 'func'


  >>> t = Test()
  >>> dir(t)
  ['__class__', '__delattr__', '__dict__', '__getattribute__',
  '__hash__', '__init__', '__module__', '__new__', '__reduce__',
  '__repr__', '__setattr__', '__str__', '__weakref__', 'age', 'func',
  'name']

The basic class that doesn't inherit from object has few
members:

  >>> dir(Test2)
  ['__doc__', '__init__', '__module__', 'func']

And the instances of Test2 add just what you specify as unique
to the instance:

  >>> m = Test2()
  >>> m.salary = 10000
  >>> dir(m)
  ['__doc__', '__init__', '__module__', 'age', 'func', 'name',
  'salary']

If your dir() is behaving differently than the above, you might
be using one of the Pythons that got much less wordy with the
dir().  Tim Peters added back more functionality so that dir()
searches up the class inheritance tree for a cumulative list.
All of the above is in Python 2.2.

Kirby