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.

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 :-)

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/…?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.