Adding methods to an object

Discussion in 'Python' started by Gabriele *darkbard* Farina, Oct 13, 2005.

  1. 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
     
    Gabriele *darkbard* Farina, Oct 13, 2005
    #1
    1. Advertising

  2. Gabriele *darkbard* Farina

    Guest

    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
     
    , Oct 13, 2005
    #2
    1. Advertising

  3. Gabriele *darkbard* Farina

    Guest

    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
     
    , Oct 13, 2005
    #3
  4. 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.
     
    Steven D'Aprano, Oct 13, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neo
    Replies:
    1
    Views:
    523
    Scott Allen
    Jan 7, 2005
  2. lallous
    Replies:
    1
    Views:
    302
    Bruno Desthuilliers
    Nov 13, 2009
  3. Nikita Petrov
    Replies:
    2
    Views:
    112
    Gary Wright
    Apr 6, 2008
  4. Kenneth McDonald
    Replies:
    5
    Views:
    319
    Kenneth McDonald
    Sep 26, 2008
  5. torbs
    Replies:
    1
    Views:
    129
Loading...

Share This Page