Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Adding methods to an object

4 views
Skip to first unread message

Gabriele *darkbard* Farina

unread,
Oct 13, 2005, 9:06:20 AM10/13/05
to
Hi, there is a way to add methods to an object dynamically? I need to
do something like this. I remember python allowed this ...

class A(object):
def do(s, m):
print m

@staticmethod
def init(obj):
obj.do = A.do

class Test(object):
pass

o = Test()
A.init(o)

o.do(10)

Now it gives me an error ... unbound method ...

tnx, gabriele

bearoph...@lycos.com

unread,
Oct 13, 2005, 9:16:53 AM10/13/05
to
This isn't code of mine, it's probably from the cookbook, maybe with
little changes:

| def addMethod(object, method, name=None):
| if name is None: name = method.func_name
| class newclass(object.__class__):
| pass
| setattr(newclass, name, method)
| object.__class__ = newclass

name is the name for the new method, if it's None then the name of
"method" is used.

Bye,
bearophile

rcram...@gldd.com

unread,
Oct 13, 2005, 9:47:24 AM10/13/05
to
gabriele,

This works (A, Test, and o as defined by you):

>>> a=A()
>>> o.do(a, 10)
10

Your problem is that do() really has two parameters, an A instance and
whatever you want to print.

Why not do this:

>>> def newdo(m):
... print m
...
>>> newdo(10)
10
>>> o=Test()
>>> o.newdo = newdo
>>> o.newdo(10)
10

Robert

Steven D'Aprano

unread,
Oct 13, 2005, 10:41:04 AM10/13/05
to
On Thu, 13 Oct 2005 06:06:20 -0700, Gabriele *darkbard* Farina wrote:

> Hi, there is a way to add methods to an object dynamically?

Yes. There are three different sorts of methods, and three ways of adding
them.

py> class Parrot:
... def __init__(self):
... pass
py> # Parrot is the class.
py> # Parrot() is an instance of the class.

Firstly, you want an ordinary method with a "self" parameter, as if you
had defined it when you created the class.


py> def spam(self):
... return "Spam comes from %s" % self
...
py> Parrot.spam = spam

Now we try calling it from an instance:

py> Parrot().spam()
'Spam comes from <__main__.Parrot instance at 0xed498fec>'

If you try to call spam direct from the class, it fails:

py> Parrot.spam()
TypeError: unbound method spam() must be called with Parrot instance as
first argument (got nothing instead)

The second way of adding a method is a class method. Class methods don't
know about the instance you call them from, only the class.

py> def fjords(cls):
... return "I'm pining for the fjords at %s." % cls
...
py> Parrot.fjords = classmethod(fjords)

Now we can call it from either the class or any instance, and get the
exact same result. fjords just can't see the instance, only the class:

py> Parrot.fjords()
"I'm pining for the fjords at __main__.Parrot"
py> Parrot().fjords()
"I'm pining for the fjords at __main__.Parrot"

Lastly, we can add a static method, that doesn't know about either the
class or the instance:

py> def ham():
... return "Genuine pig product."
...
py> Parrot.ham = staticmethod(ham)
py> Parrot.ham()
'Genuine pig product'
py> Parrot().ham()
'Genuine pig product'

Summary:

If you write the function with a "self" argument, and just add it to the
class, you must call that method using an instance. This is an ordinary
instance method, as if you had created the class with it.

If you write the function with a "cls" argument, you must add it to the
class with a classmethod() call, and then call it from either the class or
an instance. This method cannot access the instance that calls it, only
the class.

If you write the function without a "self" or "cls" argument, you must add
it to the class with a staticmethod() call. This method cannot access
either the class or the instance object.

--
Steven.

0 new messages