Writing a class that accepts a callback in Python?

callback, python

Solution

Python assumes that any functions bound within a class scope are methods. If you'd like to treat them as functions, you have to dig around in their attributes to retrieve the original function object:

def __init__(self, *args, **kwargs):
    super(Fruit, self).__init__(*args, **kwargs)

    # The attribute name was changed in Python 3; pick whichever line matches
    # your Python version.
    callback = self.print_callback.im_func  # Python 2
    callback = self.print_callback.__func__ # Python 3

    callback("Message from Fruit: ")

Problem

I need to write a class that allows a subclass to set an attribute with the name of a function. That function must then be callable from instances of the class. For example, I say I need to write a Fruit class where the subclass can pass in a welcome message. The Fruit class must expose an attribute print_callback that can be set. ``` class Fruit(object): print_callback = None def __init__(self, *args, **kwargs): super(Fruit, self).__init__(*args, **kwargs) self.print_callback("Message from Fruit: ") ``` I need to expose an API that is can be consumed by this code (to be clear, this code cannot change, say it is 3rd party code): ``` def apple_print(f): print "%sI am an Apple!" % f class Apple(Fruit): print_callback = apple_print ``` If I run: ``` mac = Apple() ``` I want to get: Message from Fruit: I am an Apple! Instead I get: TypeError: apple_print() takes exactly 1 argument (2 given) I think this is because self is passed in as the first argument. So how do I write the Fruit class? Thanks!

Original source