Tue 19 Apr 2005
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 ]
April 19th, 2005 at 5:39 pm
There’s another way to pass around state without user data that is neither better or worse than the example you gave but is sometimes a little more terse:
def make_print_list(user_data): def print_list(ls): print user_data print 'Here is your list' print ls return print_list obj.ListNames(reply_handler=make_print_list(user_data), ...)This trick relies on Python’s nested scopes and works quite well in many situations where a class may be overkill.
April 19th, 2005 at 5:44 pm
Oops. The whitespace was stripped out. Here’s a file with the correct formatting:
http://naeblis.cx/stuff/python-nested-funcs.txt
April 19th, 2005 at 5:48 pm
And this is why I love Ruby:
——-
Or something like that!
Compare it line by line with your Python code. I can’t stand Python, sorry.
But it’s popular!!!
April 19th, 2005 at 6:35 pm
Why does everyone who loves ruby instantly post comments to python threads? No offense. I am sure you didn’t do it to be offensive but it is one of my pet peves when enthusiests from one project start making noise in another. I think I wrote an article about it once entitled “My dad can beat up your dad”. If people put as much energy into making their project the best it can be as they do talking about how much they like their project over another one we would be in a much better place.
April 20th, 2005 at 7:30 am
You’re breaking the concepts of object orientation, as the “test” object there doesnt really represent anything: it exists only to encapsulate user_data.
Ruby can actually do things much nicer than the above example:
user_data = 12345 # some data print_list = lambda { |list| print user_data # using user_data print 'Here is your async list:' print list end async_error_handler = lambda { |e| print user_data # using user_data print 'There was an async error:' print e end obj.list_names(print_list,async_error_handler)The lambda encapsulates the scope. No need to create useless classes.
April 20th, 2005 at 8:23 am
Oh, man fraggle. DId I not just post about poluting threads? Did you just not post with another ruby comment. I have nothing against ruby it is just not the topic.
Yes, yes Python has lambda too. The class was just an example. Does Foo or Bar ever have meaning? Yet they are constantly used to show concepts. Using classes for userdata is perfectly fine. In fact I imagine people would create an Application class which would then have handlers within them. When the handler is called it would work on the application data.
BTW. obj.list_names(print_list,async_error_handler) would not work in the concept of DBus because I am not passing in the print_list and async_error_handler to ListNames which is a remote method on the bus and may have an unknow length of parameters. In python I use keywords to tag the method with the callbacks. In the bindings one could check for functions or methods being passed in since they can’t be marshaled over the bus, and assume they are callbacks. But, that would be ugly and would make the code harder to read.
April 20th, 2005 at 4:49 pm
J5: Man, that code example would be so much nicer (and much more OO) if you were using Ruby instead of Python.
::grin::
April 20th, 2005 at 4:51 pm
Get in the courner Clee. Do I have to come down to your cube and bitch slap you?
April 20th, 2005 at 5:45 pm
Would you be equally up in arms if the language hadn’t been Ruby? Say, Lisp or Smalltalk?
Closures and higher-order functions (which is, essentially, what you’re getting excited about) are great, and any good language these days should have them, but it’s not like they haven’t been around for decades.
Sure, this makes Python nicer than, say, C, but is it really surprising that when you proclaim, “Python is great because it has feature X,” that some people will point out if every decent language since the 70’s has had that feature?
April 20th, 2005 at 6:38 pm
Yes, I would have gotten pissed because the posts were in context of making bindings with Python. Notice I said “While this is not unique to python”. What I was showing was that I did not have to write extra API to bolt on userdata. Now with decorators I can make my bindings syntax much nicer for exporting dbus methods and sugnals. The old bindings had you pass in a list of the names of the methods you wanted to export which takes you out of the python flow and puts you into dbus glue code which is quite ugly. I really like Python and doing bindings in Python because there are easy ways to integrate with what a Python developer expects. In other words, the language and the bindings are very consitent with each other which creates what I like to call flow. Flow is just allowing a programmer to program without having them break out of their though process because of inconsistencies in the language or libraries. I’m not saying other languages don’t have this, but they don’t belong in a discussion about Python.
Now onto what I am really up in arms about. Noise is a big problem when trying to get work done. If I were compairing Ruby and Python then a healthy debate would have been good but I wasn’t compairing. I was just admiring the pieces of the puzzle of which the python bindings are the finished piece. I was admiring the elegance of the solution and posted one example of that. It was all part of a history of rewritting the bindings with posts like this spurring discussions with peers who could point out where there are better solutions or things I should take a look at. Now imagine these discussions were happening outdoors. Anyone can participate and add to the greater knowledge. And then image the one person comes over with little context of what is being discussed and starts saying, “look at me, I have no interest in Python, I see that is what you are descussing but I really like Ruby so here is some Ruby code that sort of looks like what you are talking about but it is in Ruby”. Ok, one of these guys is just an anoyance and I can understand the enthusiasm. Projects have a way of fostering that. But when a group of people are trying ot get work done in a narrow context it is really bad etiquette to start going off-topic. If more people start doing that pretty soon they drown out the people trying to do real work, and that is called noise. It is even worse when it is stated that such comments are off topic and then another person posts a similarly off topic comment. The discussion is open but it is not a free for all.
All I am saying is concentrate on making your own projects kick ass and don’t mind what other projects are saying. Hey anyone is free to post why they love their project in their own blogs. I’m not going to go and say mine is better. In fact my good friend Cris Lee posted a missive on why he hates Python. I thought it was nit picky but I really don’t care enough to even comment. I am secure in the fact Python rocks and other projects should be just as secure. Stop the noise bring back the funk
April 21st, 2005 at 12:38 am
Heh, a nice rant.
I do see your point, and really, I never thought of it from the “outdoor conversations” perspective. It would indeed be quite weird if some random dude came up and butted into a conversation with a random, tangentially-related topic
It’s strange that it doesn’t seem similarly unusual in this context. But then, I suppose things like slashdot and newsgroups and so on promote that sort of conversation, so it’s somewhat ingrained in the geek-culture, so to speak, at least online. Not to mention the fact that many (most?) geeks seem to lack the self-restraint to avoid evangelizing their pet/favorite technology when ‘competing’ technologies are mentioned (as you noted in the blog entry you mentioned, which I seem to recall reading), as if the fact that someone else has different preferences might imply that their own preferences are somehow ‘wrong’ or ‘inferior,’ and so they must be defended. Perhaps it’s an effect of our insecurities in other areas. Everyone wants to be right/best at something.
Anyhow, you probably don’t want to hear me ramble, as it’s also off topic, so I’ll shut up now. You were, indeed, justifiably pissed, but you managed to bring a little humor/insight to my evening, so perhaps you can take that as worth it.
July 13th, 2007 at 1:56 am
All Python related blogs/threads/comments seem to have a Ruby enthusiast come in and produce code that is analogous, but in their minds is ‘better’.
I went looking for a language that produced clarity and good OO behaviour. The candidates were Python and Ruby. Ruby felt closer to home since I was coming from Perl and using it for a week or so put me in the mindset, but after playing with Python for a day or two and comparing the two, it blew away Ruby as a language.
People cry that whitespace is dangerous and that Python requires more typing, but at least I don’t have to deal with this crud:
end
end
end
That for me was the deal maker, I will rather use self.var over @var because in my mind, it’s more correct, clarity > brevity. Someone reading Python code for the first time, will understand self.var over an arbitrary @var (when I saw this, I thought it was array ala Perl.)
I think the reason Ruby guys plague Python threads is deep down, they feel that Python is better as a language, but they dare not admit it since they’ve already picked a language. They’d rather spam the world saying how much better Ruby is, producing code that goes against the principles that led them to Ruby in the first place.
It reminds me of the days a Perl addict will come along and say:
> Haha, this could all be done in Perl like this:
!(&”%)obj!&£)%!&£)&%&£”^!”(*^*!_”£%^!”