Python best practices
fantascienza.net
fantascienza.net
finder = re.compile(r"""
^ \s* # start at beginning+ opt spaces
( [\[\]] ) # Group 1: opening bracket
\s* # optional spaces
( [-+]? \d+ ) # Group 2: first number
\s* , \s* # opt spaces+ comma+ opt spaces
( [-+]? \d+ ) # Group 3: second number
\s* # opt spaces
( [\[\]] ) # Group 4: closing bracket
\s* $ # opt spaces+ end at the end
""", flags=re.VERBOSE)r"\s" is repeated 6 times in there, each time with a comment. Is there a reason nobody uses DRY when writing a regexp?
spaces = r"\s*"
number = r"([-+]?\d+)"
bracket = r"([\[\]])"
finder = re.compile(spaces.join(["^", bracket, number, ",", number, bracket, "$"]))I always do one-off RE transformations of text in vi or even just sed, but this alone is reason enough to start writing my more complicated RE one-offs in Python.
I hardly ever see coding conventions documents that do such a good job of capturing the popular conventions without inserting quirky personal preferences. I clicked through expecting something to point and laugh at, but was pleasantly surprised!
My god how I wish everyone did this... would make life so much easier.
IMO, indent is personal preference, and as long as you're 100% consistent, and stay away from the devil-spawn tab character, you're ok.
None's truth value is false, so the above are equivalent to:
if x: ...
if items: ...
Empty sequences and mappings are also considered false, so you don't need to if len(items): ...
Instead, you should if items: ...
On a side note, does it annoy the hell out of anyone else that a sequence's length is len(foo) instead of foo.length() (or size, count, etc)? >>> x = ''
>>> if x is None:
... print 'x is None'
...
>>> if not x:
... print 'x is empty'
...
x is emptyif not self.db: self.db = bsddb.hashopen(...).
I just couldn't find out why my process spent valuable seconds apparently reading in the entire bsddb database into memory at random times -- but that's because bool(self.db) above turned into len(self.db.keys()) != 0
> x=5 || x = 5
Noooo. That first one is backwards. Extraneous spaces annoy me to no end. Makes it a pain to search for things too.
On the other hand, using newlines to break things up at commas for example, is great. But that's not applicable here.
> class fooclass: ... || class Fooclass(object): ...
Is this a joke?
> d = dict() || frequences = {}
How can you say that longer names are always better? (Is that part of the message here?) Usually most variables are throw-away so using short names should be the most common case. Similar to mathematics.
> # Use iter* methods when possible
This should mention that thread-safety is probably the most directly relevant use case for the non-iterable methods.
> # coding: latin
Better to use this:
#!/usr/bin/env python
# -*- coding: UTF-8 -*- >>> def f(l=[]):
... l.append(0)
... print l
...
>>> f()
[0]
>>> f()
[0, 0]
>>> f()
[0, 0, 0]
Unless you 1) actually want the appearance of a 'static' local variable or 2) are really careful to make a copy of the mutable before messing around with it, you'll get yourself into trouble.>>> MY_CONSTANT = ['foo', 'bar', 'baz'] >>> def f(l): ... l.append(0) ... print l ... >>> f() ['foo', 'bar', 'baz', 0] >>> f() ['foo', 'bar', 'baz', 0, 0]
I would've rewritten f as:
def f(l=[]):
print l + [0]
...unless you specifically want f to mutate its caller's variables and have documented it as such.Generally, I try to avoid mutating objects unless a.) I just created the object within the function or b.) it's specifically intended as a "long lived" data structure, i.e. something that survives multiple user interactions. For everything else, I try to use the non-mutating operations (slicing, concatenation, list comprehensions) or make an explicit copy of the argument.
It is recommended in the "official" python style guide to surround the assignment operator with a single space: http://www.python.org/dev/peps/pep-0008/
i = i + 1
submitted += 1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
Who writes like that?? I very strongly disagree. a[i+1]The authors of:
BitTorrent: https://develop.participatoryculture.org/trac/democracy/brow...
Django: http://code.djangoproject.com/browser/django/trunk/django/ut...
Pylons: http://pylonshq.com/project/pylonshq/browser/pylons/util.py
Twisted: http://twistedmatrix.com/trac/browser/trunk/twisted/python/u...
i+=2Is this a joke?
No... it is generally recommended that class names are capitalized, and any classes you create are supposed to inherit from object. This mainly comes into effect when using super().
In Python 3K, I'm pretty sure that all classes will inherit from object without having to explicitly say it.
tot = x + y
Better: sum_ = x + y
And I can't see nothing wrong with: freqs = {}
for c in "abracadabra":
try:
freqs[c] += 1
except KeyError:
freqs[c] = 1
Or: nested = [[1, 2, 3], [4], [5, 6]]
flattened = sum(nested, [])
It is worth to mention dict.setdefault(): indices = {}
for i, c in enumerate("abracadabra"):
indices.setdefault(c, []).append(i)