22

After a lot of searching, I have found that there are a few ways to add an bound method or unbound class methods to an existing instance objects

Such ways include approaches the code below is taking.

import types
class A(object):
 pass
def instance_func(self):
 print 'hi'
def class_func(self):
 print 'hi'
a = A()
# add bound methods to an instance using type.MethodType
a.instance_func = types.MethodType(instance_func, a) # using attribute
a.__dict__['instance_func'] = types.MethodType(instance_func, a) # using __dict__
# add bound methods to an class
A.instance_func = instance_func
A.__dict__['instance_func'] = instance_func
# add class methods to an class
A.class_func = classmethod(class_func)
A.__dict__['class_func'] = classmethod(class_func)

What makes me annoying is, typing the function's name, instance_func or class_func twice.

Is there any simple way to add an existing function to an class or instance without typing the function's name again?

For example, A.add_function_as_bound_method(f) will be far much elegant way to add an existing function to an instance or class since the function already has __name__ attribute.

asked May 18, 2015 at 3:01
0

1 Answer 1

53

Normally, functions stored in object dictionaries don't automatically turn into boundmethods when you look them up with dotted access.

That said, you can use functools.partial to pre-bind the function and store it in the object dictionary so it can be accessed like a method:

>>> from functools import partial
>>> class Dog:
 def __init__(self, name):
 self.name = name
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> def bark(self): # normal function
 print('Woof! %s is barking' % self.name)
>>> e.bark = partial(bark, e) # pre-bound and stored in the instance
>>> e.bark() # access like a normal method
Woof! Buddy is barking

This is a somewhat elegant way to add a method to an existing object (without needing to change its class and without affecting other existing objects).

Follow-up to Comment:

You can use a helper function to add the pre-bound function is a single step:

>>> def add_method(obj, func):
 'Bind a function and store it in an object'
 setattr(obj, func.__name__, partial(func, obj))

Use it like this:

>>> add_method(e, bark)
>>> e.bark()
Woof! Fido is barking

Hope this is exactly what you need :-)

answered May 18, 2015 at 4:07
Sign up to request clarification or add additional context in comments.

1 Comment

Assuming the bark function to be encoded in a string, is it possible to do the same during class initialization like asked in stackoverflow.com/questions/52579310/…?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.