Live data from Hacker News

Python Idioms [pdf]

safehammad.com

51–60 of 128 posts

Re: Python Idioms [pdf]

#51
post #44

As an implementor of Hy (a homoiconic lisp frontend to Python) I've found certain Python idioms to be rather infuriating of late. In particular: >>> 0 == False True Which makes the idiom of testing truthiness quite annoying in parsing code such as: def is_digit_char(s): """ Return a parsed integer from 's'.""" try: return int(s) except (ValueError, TypeError): return None Which is harmless enough except that as a pre…

Your function is_digit_char(s) is peculiar. From the name I would expect it to return a boolean, instead it returns a number or None. To write it like that and have a problem with the falseness of 0 it means that you use it in a way to both use it as conditional expression and an integer value, e.g. digit = is_digit_char('0') if digit: # fail print(digit) else: print('not a digit') You should then check for his equal…

It's a trivial example and I wouldn't focus on it too much.

It's not that peculiar -- instead of parsing the same character twice you simply return the value that you parsed or None. My inspiration was from the CLHS predicate function, DIGIT-CHAR-P [0].

The real point I was making is that Python has warts that make writing idiomatic code impractical in some situations. I suggest that practicality take precedence over purity. There are some situations that lead to non-idiomatic code and that's okay.

[0] http://clhs.lisp.se/Body/f_digi_1.htm

Update: forgot the link. :)

Update update: Perhaps peculiar to Python because all values of integers are not False except for 0 whereas in another language that doesn't have this wart, anything that isn't False is True... even 0. In other words, anything that isn't False is True. :D

Re: Python Idioms [pdf]

#52
>pets = ['Dog', 'Cat', 'Hamster']

>for pet in pets:

> print('A', pet, 'can be very cute!')

This may be nit picking but I prefer output like this:

print 'A %s can be very cute!' %(pet)

Re: Python Idioms [pdf]

#53

As an implementor of Hy (a homoiconic lisp frontend to Python) I've found certain Python idioms to be rather infuriating of late. In particular: >>> 0 == False True Which makes the idiom of testing truthiness quite annoying in parsing code such as: def is_digit_char(s): """ Return a parsed integer from 's'.""" try: return int(s) except (ValueError, TypeError): return None Which is harmless enough except that as a pre…

Why not use the Python built-in method "anystring".isdigit() ?

Re: Python Idioms [pdf]

#55
post #48

As an implementor of Hy (a homoiconic lisp frontend to Python) I've found certain Python idioms to be rather infuriating of late. In particular: >>> 0 == False True Which makes the idiom of testing truthiness quite annoying in parsing code such as: def is_digit_char(s): """ Return a parsed integer from 's'.""" try: return int(s) except (ValueError, TypeError): return None Which is harmless enough except that as a pre…

I'm surprised by your definition for a function named is_digit_char. I'd expect such a function to be something like: return len(s) == 1 and s[0] in string.digits Or return re.search('^\d$', s) Then it can be used idiomatically. The function you defined I'd call parse_int: def parse_int(s) "Return a parsed integer from 's' or None if it's not an int.""" ... Which would then be used as: i = parse_int(s) if i is None:…

I might try this... it wasn't actually named is_digit_char; I was actually writing a token parser for a "monadic" parser combinator library in Hy and my function was more idiomatically named there, integer-char? (after the CLHS function DIGIT-CHAR-P).

Re: Python Idioms [pdf]

#56

Interesting philosophical points. To me personally, testing for 'truthy' and 'falsy' values, or relying on exceptions rather than checking values in advance, feels like sloppy and imprecise programming. A string being empty or not, or an array having items or not, or a boolean being true or false, are all qualitatively totally different things to me -- and just because Python can treat them the same, doesn't mean a p…

I think the point of the article, and of idioms in general, is that they make code "better" (e.g. some combination of clearer, shorter, cleaner, etc.) for the community of coders who are familiar with the idioms. The obvious downside of idioms is that a programmer needs to learn the idioms to reap these advantages. So I suppose whether you should encourage idioms in your code base would depend on who will be working on the code base. I suspect most traditional software companies (even startups) will employ programmers who will either know the idioms of the language being used, or will be willing and able to learn them.

Re: Python Idioms [pdf]

#57
post #34

Earlier quoted context omitted.

I think part of the reasoning behind the truthy / falsy mechanic is that it's more robust. If, for whatever reason, we did: name = None instead of name = '' Then the second conditional would fail, whereas the first would still be fine.

Checking for empty strings can be done with len(mystring)==0 for this reason. In many other languages this method is standard and recommended practice. Relying on implicit conversions is just sloppy. What if that variable was never supposed to be None in the first place. Better with an exception than continuing with corrupt data. Remember another python motto: Explicit is better than implicit.

> Checking for empty strings can be done with len(mystring)==0 for this reason.

`len` blows up on None, so this blows up completely instead of just failing.

> Relying on implicit conversions is just sloppy.

There is no implicit conversion. Truthiness is a protocol, it does not convert anything anywhere.

Re: Python Idioms [pdf]

#58
post #46
post #44

Earlier quoted context omitted.

Your function is_digit_char(s) is peculiar. From the name I would expect it to return a boolean, instead it returns a number or None. To write it like that and have a problem with the falseness of 0 it means that you use it in a way to both use it as conditional expression and an integer value, e.g. digit = is_digit_char('0') if digit: # fail print(digit) else: print('not a digit') You should then check for his equal…

Logged in to post basically the same comment, then saw you already had. Essentially, no one who knows what they're doing in Python would write the function that way.

It's a trivial example. I've been writing Python since 2.3... maybe I should stop.

Re: Python Idioms [pdf]

#59
post #44

Earlier quoted context omitted.

Your function is_digit_char(s) is peculiar. From the name I would expect it to return a boolean, instead it returns a number or None. To write it like that and have a problem with the falseness of 0 it means that you use it in a way to both use it as conditional expression and an integer value, e.g. digit = is_digit_char('0') if digit: # fail print(digit) else: print('not a digit') You should then check for his equal…

It's a trivial example and I wouldn't focus on it too much. It's not that peculiar -- instead of parsing the same character twice you simply return the value that you parsed or None. My inspiration was from the CLHS predicate function, DIGIT-CHAR-P [0]. The real point I was making is that Python has warts that make writing idiomatic code impractical in some situations. I suggest that practicality take precedence over…

> In other words, anything that isn't False is True. :D

Except for `nil` (lisps, ruby), and possibly a host of other things depending on the language (empty strings in javascript).

Re: Python Idioms [pdf]

#60
post #3

I disagree with promoting try / catch. Exceptions like ValueError can really happen almost anywhere, so it is usually better to sanitize your inputs. E.g. something like: try: something = myfunc(d['x']) except ValueError: something = None The programmer's intent is probably to only catch errors in the key lookup d['x'], but if there is some bug in the implementation of myfunc() or any of the functions called by myfun…

That example would surely be better as: something = myfunc(d['x']) if 'x' in d else None

In this form you perform the lookup twice: once to test 'x' in d and then again to actually get the value d['x']. Try clauses in Python are very inexpensive if they pass (don't raise an exception), so often the try..except version would be preferable.

In any event don't optimize prematurely and use a profiler rather than guessing if performance is an issue. ;-)

Post reply on HN