Python callback functions and static methods

Steve Holden steve at holdenweb.com
Mon Jan 5 19:07:27 CET 2009


Joris wrote:
> Hello,
> 
> I'm trying to implement callback functionality in a static class.
> 
> I have a feeling that I'm doing something against the Python philosophy
> and not some programming error but any help would be appreciated.
> 
> First, a piece of proof-of-concept-code:
> *
> class Data:
> 
>     callfunc = None
> 
>     @staticmethod
>     def setCallBack(callfunc):
>         Data.callfunc = callfunc
> 
>     @staticmethod
>     def OnData(data):
>         Data.callfunc(data)
> 
> def DataCallback(a):
>     print 'I received some data: '+ a
>    
> Data.setCallBack(DataCallback)
> Data.OnData('I have new data')
> *
> 
> I have defined a class called Data, which I want to use as a "static"
> class (i.e. I will never create an instance of it). (I come from a Java
> background so forgive me calling this static)
> It contains a class variable and 2 static methods.
> 
> I also defined a separate function called DataCallback, which would just
> print the data it receives.
> 
> The goal of this is to use the Data class as a dispatcher of some chunk
> of data to whatever function I would like, settable at run-time.
> 
> When executing this script, following error occurs:
> 
> *Traceback (most recent call last):
>   File "callback.py", line 17, in <module>
>     Data.OnData('I have new data')
>   File "callback.py", line 11, in OnData
>     Data.callfunc(data)
> TypeError: unbound method DataCallback() must be called with Data
> instance as first argument (got str instance instead)
> *
> What I don't understand is why Python is expecting me to call the
> DataCallback() function with a Data instance. To my understanding, the
> DataCallback() function can be called from a static method and thus does
> not require any instance.
> 
> Can anyone point me in the right direction ?
> 
Although other posters have pointed out your mistake in strict terms, I
would like to suggest that as long as you never intend to instantiate
the class you would be better off without it, defining this
functionality as a module and using the nodule global namespace instead
of the class namespace. Something like this:

callfunc = None

def setCallBack(f):
    global callfunc
    callfunc = f

def OnData(data):
    callfunc(data)

if __name__ == "__main__":
    def DataCallback(a):
        print "I received this data:", a
    setCallBack(DataCallback)
    OnData("I have new data")
    OnData("And here's some more!")

In other words, I'm not sure what you feel the class organization is
buying you.

regards
 Steve
-- 
Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC              http://www.holdenweb.com/




More information about the Python-list mailing list