python 编码规范及习惯写法范例

python代码习惯写法:转自 http://www.fantascienza.net/leonardo/ar/python_best_practices.html

python代码编写过程中有一些习惯写法,Bad和Good是对相同代码的不同表示,其中Good是python中通用的代码编写规范。


Bad
Good
x=5
if ( (x==8) and (y>5) ) : ...
1<<5&2
return(5);
while (x<5) : ...
7.
x = 5
if x == 8 and y > 5: ...
(1 << 5) & 2
return 5
while x < 5: ...
7.0
print x,x*x+1
v[i + 1 + a] + v[i + 2 + b]
# Sometimes rules can be broken, for
# example to show grouping better:
print x, x*x + 1
v[i+a+1] + v[i+b+2]
def Function ( x ): ... def function(x): ...
class fooclass: ... class Fooclass(object): ...
d = dict() freqs = {}
# Descriptive names are often better
# But in small scopes a short name may be fine
list = [1, 2, 3]
dict = {'alpha': 0x1234}
sum = x + y
# Don't shadow builtin names
values = [1, 2, 3]
symbol_address = {'alpha': 0x1234}
tot = x + y
  "some string" and 'some string' and
"""some string""" and '''some string'''
are the same string.
mapping = { 5 :"5", 6:"6" } mapping = {5: "5", 6: "6"}
mapping = {5 : "5", 6 : "6"}
if mapping.has_key(6): ...
mapping = {5: "5", 6: "6"}
if 6 in mapping: ...
def function( x, l = [] ): ... # Generally don't use mutables as a default
def function(x, items=None): ...
    if items is None:
        items = []
if x == None: ... if x is None: ...
x = 1
if z > 5:
  var1 = 55
# Always use 4 spaces as indent
# (Or always a Tab, but it's less good)
x = 1
if z > 5:
    var1 = 55
mapping = {5 : "5", 6 : "6"}
for key, val in mapping.items(): ...
for key in mapping.keys(): ...
# Use iter* methods when possible
mapping = {5: "5", 6: "6"}
for key, val in mapping.iteritems(): ...
for key in mapping: ...
for i in range(10, 20000): ... for i in xrange(10, 20000): ...
  # Use to denote the code that has to
# run when a module is executed and not
# imported:
if __name__ == '__main__':
  # Python profiler:
python -m profile -o stats myscript.py
>>> import pstats
>>> p = pstats.Stats('stats')
>>> p.sort_stats('time').print_stats(15)
  For source code with not 7-bit ASCII
add this on top:
# -*- coding: UTF-8 -*-
# Or just, if you have less memory:
# coding: latin
al = [1, 2, 3]
for i in xrange(len(al)-1, -1, -1):
    del al[i]
items = [1, 2, 3]
del items[:]
# But often if speed isn't critical you
# can just use (but this is a different
# thing, this creates a new list):
items = []
# If you just want to remove one refence
# to the list:
del items
repeat
    xxx
until yyy
# Equals to:
while True
    xxx
    if yyy: break
  # To add a zip file containing modules
# to the search path:
sys.path.append("some.zip")
a = 5
b = 6
aux = a
a = b
b = aux
a = 5
b = 6
a, b = b, a # swap
if x < 10 and x > 2: ... if 2 < x < 10: ...
a = 5
b = 5
c = 5
a = b = c = 5
if x == 1: y = fun1(x)
else if x == 2: y = fun2(x)
else if x == 3: y = fun3(x)
else: y = None
if x == 1: y = fun1(x)
elif x == 2: y = fun2(x)
elif x == 3: y = fun3(x)
else: y = None
# But sometimes a dict is better:
funs = {1: fun1, 2: fun2, 3: fun3}
y = funs.get(x, lambda x:None)(x)
mapping = {5 : "5", 6 : "6"}
for key in mapping.iterkeys(): ...
mapping = {5: "5", 6: "6"}
for key in mapping: ...
al = [1, 2, 3]
for i in xrange(len(al)):
    print al[i]
al = [1, 2, 3]
for el in al:
    print el
al = [1, 2, 3]
for i in xrange(len(al)-1, -1, -1):
    print al[i]
al = [1, 2, 3]
for el in reversed(al):
    print el
class Test(object):
    def __init__(I, x): ...
class Test(object):
    def __init__(self, x): ...
# Compute the sum of the ...
def sum_of(x, y, z): ...
def sum_of(x, y, z): ...
    """Compute the sum of the ..."""
from operator import add
sl = ["ab", "cd", "ef"]
all = ""
for s in sl:
    all += s
# Or:
sl = ["ab", "cd", "ef"]
all = reduce(lambda x,y: x+y, sl, "")
sl = ["ab", "cd", "ef"]
all = "".join(sl)
a = "this isn't a word, right?"
a = a.replace("'", " ")
a = a.replace(".", " ")
a = a.replace("?", " ")
a = a.replace(",", "")
# .replace can be fine. This is faster:
from string import maketrans
tab = maketrans("'.?", "   ")
a = "this isn't a word, right."
afilt = a.translate(tab, ",")
values = ["stop",0,0] values = ["stop", 0, 0]
def mul(x, y): return x*y
l = [2, 3]
print apply(mul, l)
def mul(x, y):
    return x * y
l = [2, 3]
print mul(*l)
vals = [2, 3, -5, 0]
result = []
for el in vals:
    if el > 0:
        result.append(el * el)
vals = [2, 3, -5, 0]
result = [el * el for el in vals if el > 0]
l = [0] * 4
m = [l] * 4
m[1][1] = 5
print m
# One correct way to create a matrix:
m = [[0] * 4 for _ in xrange(4)]
m[1][1] = 5
print m
a = 1
print a / 2, a / float(2)
# A kind of alternative:
from __future__ import division
a = 1
print a // 2, a / 2
class Foo(object):
    def __init__(self, x, y, z):
        self.x_public = x
        self.y_private = y
        self.z_veryprivate = z
    def getx(self):
        return self.x_public
print Foo(1, 2, 3).getx()

# Generally getters and setters are not used.
# Instance names starting with _ are meant as
# 'to not mess with' by convention.
# Instance names starting with __ are private
# and receive name mangling.
class Foo(object):
    def __init__(self, x, y, z):
        self.x_public = x
        self._y_private = y
        self.__z_veryprivate = z
print Foo(1, 2, 3).x_public

finder = re.compile("^\s*([\[\]])\s*([-+]?\d+)
\s*,\s*([-+]?\d+)\s*([\[\]])\s*$")
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)
# Sometimes it's positive to indent logically those
# lines just like code.

# Sometimes it can be positive to compose REs:
spaces = r"\s*"            # optional spaces
number = r"( [-+]? \d+ )"  # Group
bracket = r"( [\[\]] )"    # Group. Closing bracket
parts = ["^", bracket, number, ",", number, bracket, "$"]
finder = re.compile(spaces.join(parts), flags=re.VERBOSE)
def function(data):
    """A comment"""
    ...implementation...
# Use doctests (or module tests):
def function(data):
    """A comment

    >>> function()
    None
    >>> function(1)
    result1
    >>> function("a")
    Traceback (most recent call last):
      ...
    TypeError
    """
    ...implementation...

if __name__ == "__main__":
    import doctest
    doctest.testmod()
    print "Tests done."

x = (1, 2, 6, 55, 63, 96, 125, 256, \
     301, 456, 958, 1256, \
     1359, 2568, 3597)
x = (1, 2, 6, 55, 63, 96, 125, 256,
     301, 456, 958, 1256,
     1359, 2568, 3597)
# Too much long lines must be broken with \
# but \ isn't necessary inside () [] {}
from Tkinter import *
from mymodule import *
import Tkinter as tk
from mymodule import fun1, Class1, baseconvert as bc
import psyco
psyco.bind(myfun1)
a = [3.56, 2.12]
try:
    import psyco
    # Psyco classes may be very useful
    from psyco.classes import __metaclass__
    psyco.bind(myfun1)
except ImportError: pass

# Using psyco array.array of double and
# signed long become very fast
import array
a = array.array("d", [3.56, 2.12])
# In some situations arrays of chars too are fast

# psyco can be slow with itertools, map, filter
# and generators, but fast with list
# comprehensions. For max speed with Psyco
# use low level coding style.
  # to print strings without spaces between:
from sys import stdout
stdout.write(string1)
stdout.write(string2)
  This is good enough:
words = ['me', 'do' 'bye', 'taz', 'foo', 'bar']
A shorter, more readable, but slower alternative:
words = 'me do bye taz foo bar'.split()
# sorting on the second item of the tuple
# try to remove the i index from the temporary tuples
lp = [(5J,"b"),(2J,"c"),(3+1J,"a"),(1+2J,"a")]
lp2 = [(c, i, n) for i,(n, c) in enumerate(lp)]
lp2.sort()
print [(n, c) for (c, i, n) in lp2]
from operator import itemgetter
lp = [(5J, "b"), (2J, "c"), (3+1J, "a"), (1+2J, "a")]
print sorted(lp, key=itemgetter(1))
vals = [5, 7 ,8]
tot = -2.0
for v in vals:
    tot += v
vals = [5, 7 ,8]
tot = sum(vals, -2.0)
ll = [[1, 2, 3], [4], [5, 6]]
print sum(ll, [])
data = [[1, 2, 3], [4], [5, 6]]
result = []
for sublist in data:
    result.extend(sublist)

# Or even, for max speed
from itertools import imap
data = [[1, 2, 3], [4], [5, 6]]
result = [None] * sum(imap(len, data))
pos = 0
for sublist in data:
    lensl = len(sublist)
    result[pos : pos+lensl] = sublist
    pos += lensl
print "%s %s" % (string1, string2)
print '"' + chr(c) + '":', freq[c]
print string1, string2
print '"%c": %d' % (c, freq[c])
[' ', c][c.isalpha()] # For Python V.2.5+:
(c if c.isalpha() else ' ')
  # How to invert string, lists, etc.
alist[::-1]
astring[::-1]
# To negate (inplace) each second
#  element of alist:
result = []
for (i, v) in enumerate(alist):
    # faster than i % 2
    if i & 1 == 0:
        result.append(v)
    else:
        result.append(-v)
alist[:] = result
from operator import neg
alist[1::2] = map(neg, alist[1::2])

# Or a bit slower but easier to read:
alist[1::2] = [-el for el in alist[1::2]]
  # To shallow copy a list or dict:
# (tuples don't need to be copied)
newlist = list(alist)
newdict = dict(adict)
# Or just:
newlist = list[:]
import sys
sys.exit()
# To stop a console program:
raise SystemExit

#Or just:
exit()
if type(s) == type(""): ...
if type(seq) == list or \
   type(seq) == tuple: ...
if isinstance(s, basestring): ...
if isinstance(seq, (list, tuple)): ...
# Or even:
if hasattr(seq, "__getitem__"): ...
# But quite often in dynamic languages you
# don't test types, you just use them (look
# for duck typing), catching exception that
# may occur.
name1 = 5; name2 = 20; print name2
a = 1
b = 2
c = 3
name1 = 5
name2 = 20
print name2
a, b, c = 1, 2, 3
prima = 1
rossa = "Il colore rosso"
léger = 30
# English only for names:
first = 1
red = "Il colore rosso"
light = 30
  __del__ method of classes is
usually left undefined.
try:
    fin = file("absent_file.txt")
except:
    ...
try:
    something()
except:
    ...
# Generally specify what exception to catch:
try:
    fin = file("absent_file.txt")
except IOError:
    ...
try:
    something()
except someException:
    ...
except ImportError, IOError: ... except (ImportError, IOError): ...
bytes = array.array('B', [0] * nbytes)
# Or:
from itertools import repeat
bytes = array.array('B', repeat(0, nbytes))
# This can be much faster
bytes = array.array('B', [0]) * nbytes
freqs = {}
for c in "abracadabra":
    try:
        freqs[c] += 1
    except:
        freqs[c] = 1
# Short way:
freqs = {}
for c in "abracadabra":
    freqs[c] = freqs.get(c, 0) + 1

# Often the fastest way:
freqs = {}
for c in "abracadabra":
    if c in freqs:
        freqs[c] += 1
    else:
        freqs[c] = 1

# Or better with Python 2.5+:
from collections import defaultdict
freqs = defaultdict(int)
for c in "abracadabra":
    freqs[c] += 1

someitems = set([1, 2, 3])
somemap = {1:2, 3:4, 5:6}
print list(someitems)[0]
print list(somemap)[0]

someitems = set([1, 2, 3])
somemap = {1: 2, 3: 4, 5: 6}
print iter(someitems).next()
print iter(somemap).next()
from time import clock # This works well on Windows and Linux:
from timeit import default_timer as clock
# Or often use the timeit module



posted @ 2014-08-19 18:13  msn217  阅读(508)  评论(0编辑  收藏  举报