5 ms·
The Zen of Python (by example)
- softbuilder 15y agoTroll bait for Pythonistas. At least I hope that's what that is, because this needs some serious zen-ification otherwise. To summarize, while switching religions: "The Tao that can be expressed is not the eternal Tao". But if you're going to try to express the Zen of Python, you can do a hell of a lot better than this.
- jacobolus 15y agoIndeed. Half of it seems to be bashing popular libraries the author doesn’t like, and the other half is a mixture of extremely contrived examples, and examples that miss the point of whatever particular part of the Zen they’re supposed to illustrate.
- cysun 15y agoI thought I was missing something. I sure feel better about myself now.
- alexatkeplar 15y agoIn #3, SQLAlchemy loses because it's "complex" while JSON is "simple". In #4, SQLAlchemy loses because this time it's "complicated", whereas inlining SQL create table statements is merely "complex". Conclusion: for Hunter Blanks, SQLAlchemy can never win.
- dchest 15y ago"The order of examples is not necessarily bad first, good second." http://news.ycombinator.com/item?id=2203101 http://news.ycombinator.com/item?id=2203101
- jobeirne 15y agoIMO, #3 was more about YAGNI[1], i.e. you probably won't need the speed, integrity constraints, relations, etc. delivered by SQL, so keep your data model flexible and lightweight until a shortage of those things is actually getting in your way. I wouldn't be surprised if many people criticizing #3 had no practical experience with NoSQL and the benefits brought by its lack of baggage. [1]: http://en.wikipedia.org/wiki/You_aint_gonna_need_it http://en.wikipedia.org/wiki/You_aint_gonna_need_it
- glassx 15y agoSQLAlchemy is "complex" in both #3 and #4, so it wins in #4.
- pjo 15y agoPrevious discussion on HN: http://news.ycombinator.com/item?id=2203101 http://news.ycombinator.com/item?id=2203101
- xerula 15y agoEven as a fledgling Python coder, I found this distinctly unenlightening. But, as a biologist, the part that really bugged me were the functions that regard yeast as invertebrate animals.
- ramanujan 15y agoThe "identify this animal" example has a serious bug. This: def identify(animal): if animal.is_vertebrate(): return identify_vertebrate() else: return identify_invertebrate() should be def identify(animal): if animal.is_vertebrate(): return identify_vertebrate(animal) else: return identify_invertebrate(animal) Arguably this mix of OO and procedural code is bad as well. But less arguably, the initial example (with a simple identify function) was far better than the rewrite.
- oinksoft 15y agoIn any case the else: is pointless.
- bryanh 15y agoI dunno, I like the readability of an explicit else.
- dustingetz 15y agoits subjective, arguably a style using ternary operator is better because it is composable - it evaluates as an expression, as opposed to a series of statements. it's something the lisp and functional programming people like - no implied dependency on order in which statements execute. i dunno if this is valid python but it demonstrates the idea doSomething( identify_vertebrate(animal) if animal.is_vertebrate() \ else identify_invertebrate(animal)) doSomething( if( is_vertebrate(animal) identify_vertebrate(animal) identify_invertebrate(animal))) (doSomething (if (is_vertebrate animal) (identify_vertebrate animal) (identify_invertebrate animal))) this is part of "referential transparency", and once you get past "OMG parens" you realize its a Good Thing. parens are caused by a style preferring composition of expressions over executing statements, not lisp.
- wging 15y agoThis doesn't work. I think it's an attempt at a closure, which you can do in the latest Python 3.x by `nonlocal i` as the first statement in the function definition... def make_counter(): i = 0 def count(): """ Increments a count and returns it. """ i += 1 return i return count
- pash 15y agoYou can cheat in Python 2.x by giving the inner function a keyword argument that defaults to the value you want to close over: ... def count(i=i): ... ...
- abecedarius 15y agoWon't do what's intended in this case. I tried it now just to make sure. I'd use itertools.count().
- pash 15y agoYes, I just meant to point out that there is a way to do closures in Python 2.x. Looks like here the author wants a function that saves its internal state, i.e., a generator.
- abecedarius 15y agoClosures actually do work without that trick since many versions back. It's setting a nonlocal that still sucks.
- pash 15y agoWell, they sort of work. Closures don't work properly [0] in some lexical contexts without using the default-argument trick because of the way function definition works in Python: fs = [] for i in range(5): def f(): print(i) fs.append(f) gs = [] for i in range(5): def g(i=i): print(i) gs.append(g) The functions in `fs` all print 4 because they all refer to the final object assigned to `i` in the `for` loop. The functions in `gs`, on the other hand, print 0 through 4, as they "should" because the `i` in `g` is assigned to the object currently referenced by the `for` loop's `i` each time the `def` statement is evaluated. This distinction in behavior is obscured in the classic function-inside-a-function example of closures because you pass the object to be closed over to the outer function each time you want to create a new closure. So the result is analogous to using the default-argument trick in the example above. Anyway, that's all I meant to point out. I misinterpreted your reference to `nonlocal`, which I'm not very familiar with as I don't really use Python 3 much yet. So sorry for my nonsensical reply. [0] By "properly" I mean as closures work in pure functional languages, where they originated. I realize a programmer who understands Python's data model shouldn't generally expect them to work that way in Python.
- perfunctory 15y agomake_counter and make_adder are not equivalent. How can he compare the two?
- tzury 15y agofrom menagerie.models import cat as cat_models This is not recommended at all
- zackattack 15y agoBy whom, and why not? I like it. It's explicit. Self-documenting.
- iclelland 15y agoAlso, it should have read from menagerie.cat import models as cat_models from menagerie.dog import models as dog_models from menagerie.mouse import models as mouse_models Because otherwise it doesn't match the code in the first example for #3, and also because if your packages are ordered that way, then why not just from menagerie.models import cat, dog, mouse and forget about changing the local module name.
- hblanks 15y agoHi, all. I'm Hunter Blanks (hblanks@artifex.org). Folks seem to have found a lot of implicit meaning and bugs in what was, at its grandest, a 5 minute talk at RedSnake Philly 2011. I'll just make two comments: 1) This in now up on GitHub at: https://github.com/hblanks/talks/tree/master/2011/zen_of_python_by_example.20110208 https://github.com/hblanks/talks/tree/master/2011/zen_of_pyt... so if you feel strongly about making this better, you should send me a pull request. 2) People seem to have decided that the top (or the bottom?) of every example is the more pythonic one. I suppose I should have kept a consistent order, but, as I noted in the initial HN thread, that just wasn't necessary since this was delivered in the context of a talk.