TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Python Idioms [pdf]

237 pointsby benn_88over 11 years ago

23 comments

crazygringoover 11 years ago
Interesting philosophical points.<p>To me personally, testing for &#x27;truthy&#x27; and &#x27;falsy&#x27; values, or relying on exceptions rather than checking values in advance, feels like sloppy and imprecise programming.<p>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 <i>can</i> treat them the same, doesn&#x27;t mean a programmer <i>should</i> take advantage of that fact. Sometimes it&#x27;s possible to <i>over</i>-simplify things in a way that obfuscates instead of clarifying.<p>When I read:<p><pre><code> if name and pets and owners </code></pre> I have no intuitive idea of what that means, of what&#x27;s going on in the program. When I read<p><pre><code> if name != &#x27;&#x27; and len(pets) &gt; 0 and owners != {} </code></pre> I understand it exactly.<p>But by this point, I&#x27;ve come to understand that, for a lot of people, it seems to be the opposite. It seems to be more of a philosophical difference, not right&#x2F;wrong.
评论 #7153338 未加载
评论 #7152033 未加载
评论 #7152713 未加载
评论 #7152192 未加载
评论 #7151989 未加载
评论 #7153539 未加载
评论 #7152948 未加载
评论 #7152410 未加载
评论 #7152869 未加载
csenseover 11 years ago
I disagree with promoting try &#x2F; catch. Exceptions like ValueError can really happen almost anywhere, so it is usually better to sanitize your inputs.<p>E.g. something like:<p><pre><code> try: something = myfunc(d[&#x27;x&#x27;]) except ValueError: something = None </code></pre> The programmer&#x27;s intent is probably to only catch errors in the key lookup d[&#x27;x&#x27;], but if there is some bug in the implementation of myfunc() or any of the functions called by myfunc() which causes a ValueError to unintentionally be raised, it will be caught by the except.<p>For dictionary lookups specifically, get() is usually preferable:<p><pre><code> something = d.get(&#x27;x&#x27;) if something is not None: something = myfunc(something) </code></pre> Or if dictionary may potentially contain None values:<p><pre><code> if &#x27;x&#x27; in d: something = myfunc(d[&#x27;x&#x27;])</code></pre>
评论 #7152181 未加载
评论 #7151852 未加载
评论 #7151778 未加载
评论 #7151863 未加载
评论 #7155562 未加载
Walkmanover 11 years ago
For point 10:<p>&#x27;_&#x27; is often aliased as gettext to ease translation of string:<p><pre><code> from django.utils.translation import ugettext as _ translated_str = _(&#x27;Something to translate&#x27;) </code></pre> so using it will overwrite the alias. Instead, you can use &#x27;__&#x27; (double underscore) as ncoghlan suggests below his answer [1]. or you can use the &#x27;unused_&#x27; prefix as Google Python Style Guide suggests [2] or you can change your code, so you don&#x27;t need to use &#x27;_&#x27; as Alex Martelli suggests in his answer [3].<p>[1]: <a href="http://stackoverflow.com/a/5893946/720077" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;5893946&#x2F;720077</a><p>[2]: <a href="http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Lint#Lint" rel="nofollow">http:&#x2F;&#x2F;google-styleguide.googlecode.com&#x2F;svn&#x2F;trunk&#x2F;pyguide.ht...</a><p>[3]: <a href="http://stackoverflow.com/a/1739541/720077" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;1739541&#x2F;720077</a>
评论 #7152277 未加载
评论 #7161727 未加载
udevover 11 years ago
One of the handy things not mentioned:<p><pre><code> with open(&quot;x.txt&quot;) as f: data = f.read() # do something with data</code></pre>
评论 #7152440 未加载
jzwinckover 11 years ago
The very first one, &quot;Make a script both importable and executable,&quot; needs some caveats. It&#x27;s useful sometimes, but people often use it in places where it is not a great idea. Here&#x27;s why:<p>1) If you are in the mindset of &quot;I want a single file which is both a library and a program,&quot; how will you name it? Files to import must end with &quot;.py&quot; and follow C-style name rules, so cannot start with a number cannot contain hyphens. This leads many people to break conventions when naming their programs, because on Unix, hyphens are conventional in program names but underscores are not (count the examples of each in &#x2F;usr&#x2F;bin on any system). And naming your program something like &quot;2to3&quot; is impractical if you want it to be importable also.<p>2) It is unclear where to install files which are both programs and libraries. Programs usually go in some sort of &quot;bin&quot; directory (again, on Unix systems), but libraries do not. Where do you put a file which is both?<p>3) Sometimes the __name__ == &#x27;__main__&#x27; trick is used to include unit tests within a module. That&#x27;s not bad, but consider using Python&#x27;s excellent doctest feature instead, which often serves the same need but in a richer way.
评论 #7155398 未加载
simon_weberover 11 years ago
&gt; 9. Create dict from keys and values using zip<p>In 2.7+, I&#x27;d recommend a dictionary comprehension instead.
评论 #7151910 未加载
评论 #7154258 未加载
agentultraover 11 years ago
As an implementor of Hy (a homoiconic lisp frontend to Python) I&#x27;ve found certain Python idioms to be rather infuriating of late.<p>In particular:<p><pre><code> &gt;&gt;&gt; 0 == False True </code></pre> Which makes the idiom of testing truthiness quite annoying in parsing code such as:<p><pre><code> def is_digit_char(s): &quot;&quot;&quot; Return a parsed integer from &#x27;s&#x27;.&quot;&quot;&quot; try: return int(s) except (ValueError, TypeError): return None </code></pre> Which is harmless enough except that as a predicate it sucks because parsing &quot;0&quot; will return False in a context where I&#x27;d rather know whether I parsed an integer or not... which leads to non-idiomatic code.<p>This is mainly because True&#x2F;False are essentially aliases for 1&#x2F;0 and as such won&#x27;t identify so:<p><pre><code> &gt;&gt;&gt; 0 is False False &gt;&gt;&gt; 0 is 0 True </code></pre> So it&#x27;s important to remember another Tim Peters-ism: <i>Although practicality beats purity.</i> As read in the Zen of Python it seems he&#x27;s referring to special cases which this might be.<p>As a shameless aside, you should see what we&#x27;re working on in Hy. There will likely come a point where we&#x27;ll be able to do kibit-style suggestions of idiomatic transformations to your Python code.<p><i>Update</i>: I ran into this while trying to write token parsers for a parser-combinator lib in Hy.
评论 #7152340 未加载
评论 #7152415 未加载
评论 #7152906 未加载
评论 #7152131 未加载
评论 #7152604 未加载
jackmaneyover 11 years ago
Although many of them boil down to preferences and philosophical points of view, I find these kinds of idioms useful. Whenever I write code in a new language, I want to &quot;write as a native&quot; so that I can maximize the effect that the language has on how I think about programming.<p>For Python in particular, Jeff Knupp&#x27;s &quot;Writing Idiomatic Python&quot;[1] (not free, but not expensive, either) goes into detail on a lot of the concepts in the OP&#x27;s slides. (I&#x27;m not affiliated with Jeff in any way, just a satisfied customer.)<p>[1] <a href="http://www.jeffknupp.com/writing-idiomatic-python-ebook" rel="nofollow">http:&#x2F;&#x2F;www.jeffknupp.com&#x2F;writing-idiomatic-python-ebook</a>
评论 #7153457 未加载
jfischerover 11 years ago
Alex Martelli gave a nice talk called &quot;Permission or Forgiveness&quot; about the exception handling style recommended by OP: <a href="http://pyvideo.org/video/1338/permission-or-forgiveness-0" rel="nofollow">http:&#x2F;&#x2F;pyvideo.org&#x2F;video&#x2F;1338&#x2F;permission-or-forgiveness-0</a>. He has some nice insights into this issue.<p>That being said, I think there are some situations where you want to check for problems up front (possibly in addition to exception handling). In particular, if you are parsing some data from outside the program, you may want to provide some context about what was wrong. KeyError is not very helpful to your users.
Vaskivoover 11 years ago
As a huge Python fan, I&#x27;m ashamed to admit but I don&#x27;t get the<p><pre><code> while True: break </code></pre> What&#x27;s the problem? I supose the use case is<p><pre><code> while True: # do stuff if some_condition: break </code></pre> What is the alternative? &#x27;while some_condition&#x27;? That means we must have the &#x27;some_condition&#x27; variable outside of the loop. And if we have multiple exit points it may become a mess.
评论 #7152201 未加载
评论 #7152092 未加载
评论 #7152244 未加载
评论 #7152023 未加载
评论 #7152075 未加载
aarenover 11 years ago
I would add generator expressions:<p><pre><code> (f(x) for x in list_of_inputs) </code></pre> Just like a list comprehension, but with (...) rather than [...] and with lazy evaluation.<p>These are useful when you don&#x27;t need to evaluate all of the inputs at once but still want to iterate over them at some point later on.
评论 #7153684 未加载
kerpalover 11 years ago
Thanks for this write up. I didn&#x27;t know about enumerate. I never thought of swapping variables as in example 4 either.<p>I noticed one small mistake in section 9:<p><pre><code> d[keys] = values[i] </code></pre> Should be:<p><pre><code> d[key] = values[i]</code></pre>
评论 #7154419 未加载
calrocover 11 years ago
This is a great, if somewhat basic list. My $0.02: Python is a tool for thinking clearly. That you can run your &quot;thoughts&quot; as written is a very nice bonus, of course.<p>There are some really interesting things that Python allows:<p><pre><code> &gt;&gt;&gt; d = {} &gt;&gt;&gt; d[23], d[14], d[&#x27;hmm&#x27;] = &#x27;abc&#x27; &gt;&gt;&gt; d {&#x27;hmm&#x27;: &#x27;c&#x27;, 14: &#x27;b&#x27;, 23: &#x27;a&#x27;}</code></pre>
评论 #7152882 未加载
hyperbovineover 11 years ago
His last slide could be written more idiomatically as<p><pre><code> &#x27;&#x27;.join(&#x27;Thanks!&#x27;)</code></pre>
评论 #7152011 未加载
评论 #7153595 未加载
mangelettiover 11 years ago
Srsly, what Python programmer writes the code in the &quot;Bad&quot; examples therein? This list looks like it&#x27;s from 2005 or something.
评论 #7155919 未加载
malkiaover 11 years ago
On page 20, there is slight mistake - count is used in the second (&quot;NOT SO GOOD&quot;) example but &quot;i&quot; is printed.
评论 #7157183 未加载
juanuysover 11 years ago
On page 20, didn&#x27;t he&#x2F;she mean &quot;print(count, name)&quot; in the BAD example?<p>On page 18, the Java comment: it depends. E.g. see [1]<p>[1] <a href="http://stackoverflow.com/questions/299068/how-slow-are-java-exceptions" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;299068&#x2F;how-slow-are-java-...</a>
gabipurcaruover 11 years ago
Another one that I find useful -- using `map` instead of list comprehensions when you want to apply a function to every element. So instead of:<p><pre><code> [str(x) for x in array] </code></pre> Do this:<p><pre><code> map(str, array)</code></pre>
drewblayover 11 years ago
&gt;pets = [&#x27;Dog&#x27;, &#x27;Cat&#x27;, &#x27;Hamster&#x27;]<p>&gt;for pet in pets:<p>&gt; print(&#x27;A&#x27;, pet, &#x27;can be very cute!&#x27;)<p>This may be nit picking but I prefer output like this:<p>print &#x27;A %s can be very cute!&#x27; %(pet)
评论 #7153474 未加载
评论 #7152849 未加载
Redoubtsover 11 years ago
I don&#x27;t understand the truth table on slide 9 for &quot; - vs None &quot; and &quot;__nonzero__ (2.x) &quot; __bool__ (3.x) vs __nonzero__ (2.x) &quot; __bool__ (3.x) &quot;
评论 #7151967 未加载
评论 #7152007 未加载
myleover 11 years ago
String concatenation is pretty fast nowadays with the + operator.
评论 #7157098 未加载
mrfusionover 11 years ago
I&#x27;d love to see a writeup like this for Perl or Javascript. Has anyone come across one?<p>How about Java?
rafekettover 11 years ago
i agree with all but #2. this seems to embrace conciseness as simplicity or understandability. it forgets the more cardinal value that explicit is better than implicit.