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?

Hierarchy: previous, next

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.

Alastair Tse

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'

Testarossa

Related:

http://coffeeghost.net/2008/03/19/your-ignorance-does-not-make-a-programming-language-suck/

Simon

@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.

Sim

>>> 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.

 

This is the official Semacode Weblog!

Browse the weblog archives

Subscribe to the full-text RSS feed or the comments RSS feed.

Tags: