ruby rocks, python not
Posted by Simon on March 18, 2008 at 09:54 PM
So I'm just doing some python programming, just a few hours, and already I'm missin' ruby.
python dictionary, is a certain key set?
if self.params['foo']:
oh no, that's won't work. Hmm... How about
if defined(self.params['foo'])
Nope... no such luck, there's NO WAY to find out if a variable is defined in python. Finally after futzking around online I find out that the ONLY way to do it reliably in any situation is to—get this—catch an exception. Except since I'm dealing with a dictionary I can use this (undocumented) method:
if self.params.has_key('foo'):
That's so lame. In ruby, you can do any of these:
if @params['foo']
if @params['foo'].nil?
if defined? @params['foo']
Speaking of which, now that I get it, the @foo syntax for an instance variable (stupidly called a "data attribute" in python) is great. So much more obvious & compact than self.foo.
Python also forces you to do some things that I have happily adapted to giving up in ruby. Like calling functions without brackets, isn't
defined? @params
so much prettier than
defined?(@params)
Yes it is. And also, I've started naming my functions with ?s if they yield a boolean and ! if they make a change in place or generally perform a destructive edit—nice.
And ruby's blocks—I love you!
download = Download.new do |d|
d.user = @user
d.name = my_name
end
And
unless and the if/unless modifiers... I could go on forever. Why don't you read the insane book?
This is the official Semacode Weblog!
Subscribe to the full-text RSS feed or the comments RSS feed.
Tags:

Comments
There are 7 comments on this post. Post yours →
"Nope... no such luck, there's NO WAY to find out if a variable is defined in python."
It's actually easy in Python:
>>> self = {'foo': 'bar', 'baz': 'bap'}
>>> self.has_key('foo')
True
>>> self.has_key('blarg')
False
For individual variables, rather than dictionary keys, you can test using the same has_key() method, but for the locals() dictionary:
>>> foo = 'bar'
>>> locals().has_key('foo')
True
>>> locals().has_key('baz')
False
Easy, peasy.
It's actually just:
params = {
'foo': 1,
}
if 'foo' in params:
print 'self.params['foo'] ok'
if 'bar' in params:
print 'self.params['bar'] ok'
Related:
http://coffeeghost.net/2008/03/19/your-ignorance-does-not-make-a-programming-language-suck/
@Ryan: that method is not only ugly, but also unreliable: see http://mail.python.org/pipermail/python-list/2002-July/156865.html (since the variable is from an outside scope, it's neither local or global......)
@Alastair: that is certainly better, but not as good as simply testing it directly as in ruby. It should Just Work.
@ Testarossa: Fortunately, python doesn't actually SUCK. Then I wouldn't use it (Perl does suck, so I don't use it). But ruby is better.
Simon,
The problem you cited in your post was testing whether a dictionary contains a key. I mentioned one way, and Alastair mentioned a better one:
>>> params = {'foo': 1}
>>> key1 = 'foo'
>>> key2 = 'bar'
>>> key1 in params
True
>>> key2 in params
False
As far as I can see, this syntax *is* just testing it directly. :)
As for the more general problem of discovering whether a variable has been initialized, thanks for pointing out the problem with the method I gave. It does appear that a try / except block is the only way to be certain.
However, as one Pythonista put it:
"Personally, I find it quite nice
that an ugly architecture (such as one based on whether a variable
is already defined/initialized rather than initializing it at the
start with a unique value and testing for that!) requires an ugly
way of expressing it."
http://www.thescripts.com/forum/thread20887.html
Cheers!
I made a text selection in my web browser, right clicked and Googled for "python dictionary, is a certain key set". Even the number one ("I'm feeling lucky!") link that comes up answers your question.
Tired: Ignorance. Wired: Learning.
>>> params = {'foo': 1}
>>> key1 = 'foo'
>>> key2 = 'bar'
>>> try: print 'key1:', params[key1]
... except KeyError: print 'not set'
...
key1: 1
>>> try: print 'key2:', params[key2]
... except KeyError: print 'not set'
...
key2: not set
Yet another way to do it that is usually my favorite since I believe it is actually faster.
-Sim
Post a comment
Required fields in bold.