Add methods to a class at runtime?
Gerhard Häring
gerhard.haering at gmx.de
Sun Sep 1 14:44:39 EDT 2002
Robert Oschler wrote in comp.lang.python:
> "Gerhard Häring" <gerhard.haering at gmx.de> wrote:
>> >>> 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
>> >>>
>
> Gerhard,
>
> Thanks but I need a little bit more detail. Suppose I want to do it from
> within code? For example, I create a function called
> AddBarToFoo(FooObject), that given a object of type Foo (FooObject) adds the
> Bar method to it dynamically, what would be the syntax then?
To get the class of an instance, you can query its __class__
attribute.
> Would I have to put the method declaration code, which you show
> being typed in to the interpreter, in a string and then eval/exec
> it?
No, you hardly ever need to use eval or exec. Sometimes you only want
to "specialize" an existing, more generic function. For a real-life
example, here's something I experimented with yesterday:
# [snip generic_insert, generic_update]
def generic_delete(tablename, id):
cursor = getdb().cursor()
statement = "DELETE FROM %s WHERE id=%%s" % tablename
cursor.execute(statement, (id,))
def make_functions(tablename):
globals()[tablename + "_DELETE"] = lambda id: generic_delete(tablename, id)
# Create a specialized DELETE function for the table TEST which will
# be named TEST_DELETE (this will be a specialized generic_delete):
make_functions("TEST")
# Execute the newly created function:
TEST_DELETE(25)
I never really needed to add methods to classes on-the-fly, but the
above technique came in useful a few times. One other thing I found
useful is dynamically creating a new class (with certain class
attributes) using the new module.
As in certain other languages starting with "P", not everything you
/can/ do in Python is actually very useful, or necessarily a good
idea.
Gerhard
--
mail: gerhard <at> bigfoot <dot> de registered Linux user #64239
web: http://www.cs.fhm.edu/~ifw00065/ OpenPGP public key id AD24C930
public key fingerprint: 3FCC 8700 3012 0A9E B0C9 3667 814B 9CAA AD24 C930
reduce(lambda x,y:x+y,map(lambda x:chr(ord(x)^42),tuple('zS^BED\nX_FOY\x0b')))
More information about the Python-list
mailing list