Because you solve problems like this cleanly:

def print_list(list):
    print 'Here is your async list:'
    print list

def async_error_handler(e):
    print 'There was an async error:'
    print e

obj.ListNames(reply_handler=print_list, error_handler=async_error_handler)

But where is the API for user data? How can I pass in variables I need to work on without making them global? Your API sucks because handlers are useless without external data!!!

class test:
    def __init__(self, user_data):
        self._user_data = user_data
        obj.ListNames(reply_handler=self.print_list, error_handler=self.async_error_handler)

    def print_list(self, list):
        print self._user_data
        print 'Here is your async list:'
        print list

    def async_error_handler(self, e):
        print self._user_data
        print 'There was an async error:'
        print e

test('I can now work on userdata')

While this is not unique to python the ability to pass in methods that retain a refrence to an instance of their class means no added binding code for passing in user data. It just flows better when one can use a languages own constructs to obtain the desired functionality instead of each binding writter figuring out how to do it themselves. There are other ways to do this too in python but I won’t go into those.

I also like the whole keyword design. Without keywords it would have been harder or at least a bit more ugly for us to support async calling. API would have had to been added to register callbacks on individual methods. With keywords I was able to add what seems like extra parameters to the DBus calls making it cleaner in my opinion. Since DBus doesn’t support keywords as arguments there is no worries of clashes. I still have to worry about possible future namespace clashing with python itself (which is why we use dbus_interface instead of just interface) but I have a feeling it will not pose a problem.

[read this post in: ar de es fr it ja ko pt ru zh-CN ]