Add methods to a class at runtime?

Robert Oschler Oschler at earthlink.net
Sun Sep 1 17:19:36 EDT 2002


"Gerhard Häring" <gerhard.haering at gmx.de> wrote in message
news:slrnan4dl3.18h.gerhard.haering at lilith.my-fqdn.de...
> >>> class Foo: pass
> ...
> >>> foo = Foo()
> >>> foo.bar()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> AttributeError: Foo instance has no attribute 'bar'
> >>> def bar(self): print "bar"
> ...
> >>> Foo.bar = bar
> >>> foo.bar()
> bar

Ok bear with me guys (Gerhard and Peter).  I'm not lazy, the reason I don't
test certain things I should is because Python is capable of such amazing
introspective dynamism that, having a _very_ long experience bank in
strongly typed "static" languages like C++ and Pascal, I find I don't even
consider yet even trying certain possibilies that Python is capable of.
Some interesting tidbits I found while trying out your suggestions,  as you
will see in the two ".py" files that follow, I discovered that to create a
method you can dynamically add to a class _instance_, you need to omit the
'self' parameter in the method declaration.  For a method you add
dynamically to a class definition itself, then you must include the 'self'
parameter in the method declaration.  If not, you will get an argument count
mismatch complaint from the interpreter.  Fascinating stuff.

I'm running 2.1.1, anybody know if 2.2.2 is going "disable" either of these
abilities? (class or class instance dynamic method addition).  I saw a note
about such activities requiring a "dynamic" keyword, which is fine.  I'd
really miss either of these abilities.  Code follows below,

Thanks again.

-------------------------------------------------------------


// The test program, test_main.py.

import test1
a = test1.Account("Guido", 1000)
a.MethodToAdd = test1.MethodToAddToInstance
a.MethodToAdd()

test1.Account.MethodToAdd = test1.MethodToAddToClass
c = test1.Account("Fred", 2000)
c.MethodToAdd()

// The module test1.py.

class Account:
  "A simple class"
  account_type = "basic"
  def __init__(self, name, balance):
    "Initialize a new account balance"
    self.name = name
    self.balance = balance
  def deposit(self, amt):
    "Add to the balance"
    self.balance = self.balance + amt
  def withdraw(self, amt):
    "Subtract from the balance"
    self.balance = self.balance - amt
  def inquiry(self):
    "Return the current balance"
    return self.balance

def AddAttr(Acct):
  Acct.number = 7

def MethodToAddToInstance():
  "I want to add this method dynamically to an instance of a class."
  return 10

def MethodToAddToClass(self):
  "I want to add this method dynamically to a class."
  return 11









More information about the Python-list mailing list