For example, explicit isn't always better than implicit. I mean, by that standard alone, the idea of a garbage collector going around implicitly freeing memory would be terrible.
And then, in our very first example, there is a use of lambda, a misnomer of a concept Python doesn't really support? My brow furrowed slightly more.
I can't help but feel like these people are celebrating their investment in their tools rather than the virtues of the tools themselves.
Yes, but this practically is the Python manifesto.
Python 2.6.5 (r265:79063, Oct 28 2010, 20:56:23)
[GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
There's an import statement that will print it I believe, but I'm not sure exactly what it is.
numbers.filter( _ % 2 == 0 )
numbers.filter( _ % 2 == 0 ).map( _ / 2 )
How do you write:
lambda x, y=1: x+y
lambda *args: reduce(lcm, args)
lambda **kwargs: kwargs.get('a') or kwargs.get('b')
def lcm(a, b):
return a*b // gcd(a, b)
def gcd(a, b):
a, b = b, a % b
It does indeed mention a lambda in the very first example, if only as a competition with list comprehension syntax. But even Python's list comprehensions look a little dated now.
What do you mean by dated? What new ideas have come up for List comprehension syntax?
(I agree that Lambda should be call fun or fn or \. An implicit _ might also work, though that's somewhat against Python's spirit---c.f. the explicit self in methods.)
The part that bothers me about the list comprehension section is that conflating list comprehension and lambda. Is it telling me that list comprehension is better than map/filter or better than lambda? I don't know. Quiet honestly, in many situations I find:
halves_evens = lambda nums : [i/2 for i in nums if nums % 2 == 0]
to be the cleanest.
for i in nums:
div, mod = divmod(i, 2) #NOTE: it might be slower
if mod == 0: #NOTE: `not mod` is not explicit enough
#3: `users` is not defined. `sqlalchemy` names are not defined. The file should be opened for writing in the json example.
#5 It is simpler to allow the animal to know its kind:
for a in elem.find(’./a’)
if ’href’ in a.attrib]
There is no `lxml.CSSSelector` (python-lxml 2.2.6-1). Use `elem.cssselect`
#7 You don't need to add `ifmain` stub in every module:
$ python -mdoctest module_with_doctests.py
$ python -munittest module_with_unittests.py
Despite the fact that it works on my machine on all available Python implementations such code should be avoided:
assert float(’0.20000000000000007’) == 1.1 - 0.9 #XXX horror!
try: import json
import simplejson as json
#13 `__builtins__` is not defined on jython:
try: import __builtin__ as builtins
import builtins # py3k
In general globals should be written at a global level.
> #2: Function level import is a bad practice though
> it might be justified in this case.
> Special cases aren't special enough to break the rules.
This isn't meant to detract from the truth that "Beautiful [code] is better than ugly," I merely thought the implementation should be correct.
I think i % 2 is just straight up incorrect.
If we're talking about style, I think i % 2 == 0 is much more clear than (not i % 2). It says explicitly that the remainder of i divided by 2 is 0.
>>> not 0
i % 2 == 0
if len(foo) > 0:
class ExtendedBool t where
toBool :: t -> Bool
instance ExtendedBool Int where
toBool = (0/=)
instance ExtendedBool [a] where
toBool = not . null
if' v a b =
if (toBool v)
main = if' "String"
That said, I'm having quite a hard time grappling with section 4.
First, what is the 'users' keyword all about in the "bad" area?
Second, why is ORM the "bad" approach, and manual construction of SQL strings the "good" one? It seems to me that the abstraction and centralization of query language is paramount (examples: to afford oneself an easy one-day migration to GQL/BigTable, or to a document-oriented database like MongoDB or the upcoming Couchbase).
You could argue "between Python and C"... but most certainly NOT assembler
http://www.wefearchange.org/2010/06/import-this-and-zen-of-p... , a blog post written by Barry warsaw.
On a side note, other eggs are :
>>> from __future__ import braces
>>> import antigravity
I agree with several commenters that, like any collection of aphorisms,
the lines in PEP 20 are not real rules but rather rules of thumb.
Nevertheless, rules of thumb, or heuristics, are surprisingly important
to the practice of engineering,* and perhaps even more so to the work of
writing software. As such, nothing in PEP 20 should be followed hard and
fast, but almost all of it is worth considering. Also as such, there's
nothing (except for the comment on Guido) that makes PEP 20 relevant
only to Python. It happens that these rules have a particular currency
in the Python community (i.e., when people talk about being Pythonic,
they're often talking about something described in the Zen of Python).
But if you work in a different language, there's probably something
worthwhile in it there, too.
On a different note, it is flattering to find this code, hacked out such
as it was, has been reviewed by a far larger number of peers than the
(comparably) few, albeit exceptional, engineers I work with at Monetate.
Although it was hardly intended to be read on its own, or to run beyond
the feeble purpose of generating its own slides, I have tried to correct
what errors people have found. Ambiguities, of course, remain, but you can find an updated document at the
original URL, or a diff of the changes at:
- Yes, of course, importing from within in a function is almost always a bad idea (the only exception I've ever seen is Google App Engine, and that's obviously just a performance hack). Nor would you ever want to actually convert your floats to strings and back -- my only point there was to illustrate the fact that yes, those are the rules of floating point, and so you can't expect Python to break them for repr().
- The order of examples is not necessarily bad first, good second. (Alas for inconsistency!) So, for instance, ORMs may be complex, but they're often much better than writing your own SQL, which even in this trivial example starts to get complicated. Similarly, doctests often make code more readable than unit tests hiding in some other file -- although in honesty the doctest/unittest split is probably a false dichotomy; for some things, doctest is much cleaner, for others (like things that require setting up a DB schema first), unit tests are.
- Finally, I still didn't have the wherewithal to call pygments directly (it's certainly easy and better; I just knew the command already). But I did add HTML output, since this the web, after
We've finally accepted that web developers can expect visitors to have a higher resolution than VGA, and those are potentially non-tech-savvy users. Can't we expect developers to have more than 80 character width editors? Plus, I think splitting lines is pretty ugly.
Finally, in some cases, it's just more readable. Take the following code:
some_list = [a_long_variable, with_contrived_names, for_an_example, insert_your, own_parallel, if_it_bothers_you]
some_list = [
(Of course I have a second monitor, but that usually has documentation and a terminal and IRC on it.)
When text stretches to take up the entire width I don't use full-screen windows. I adjust them to have about 10 words per line, and I can scan down really fast. Similarly for programming. Don't make me scroll through a 6000 line function, and don't make me read along a 6000 character line.
Yes, 6000 characters may be an exaggeration, but where is the limit? Where is the point where the line is simply "too long". Answer? It's where readability drops off, and for me, that's about 10 words, or about 60 characters.
Also, the restriction to something around 80 characters stemmed from technical considerations---but it may be good for readability, too. After all 66 characters per line is the rule of thumb for type setting books. Newspapers also divide their pages into narrow columns.
However, since everyone is shipping widescreen monitors (which I think means UI design should stop making tall toolbars, but I digress), I find that a width of 100 characters suits my code better.
Can somebody please enlighten me on how using raw sql is preferable?
ORMs are not a panacea. Especially when the database schema gets more complicated they require more setup and tuning, and there's always the problem of how much data the ORM should suck in vs. how lazy it can behave.
evens_only = lambda nums: [n/2 for n in nums if n%2==0]
evens_only = lambda nums: (n/2 for n in nums if n%2==0)
<generator object <genexpr> at 0x7f2ef79eaa00>
I do not claim to be a master