Python Language Rules

Google 正在使用的Python 语言规则,翻译自下面链接

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Python_Language_Rules

1. Lint

使用在你的代码上运行pylint,lint是一个帮助开发人员找bug和风格问题的工具。

2. Import

因为有些module 名字比较短,所以说出现冲突的情况,解决方法是如果module 名字有冲突,加上包名。

3. Packages

新的代码应该导入每个模块的全路径名。

# Reference in code with complete name.(不推荐的)
import sound.effects.echo

# Reference in code with just module name (preferred).(推荐的)
from sound.effects import echo

4. Exceptions

使用异常意味着要打断正常的控制流程,所以使用的不好会导致控制流程混乱,而且在使用别人的库时,很容易丢失异常的情况。

抛出自定义异常时使用

raise MyException('Error Message')
or 
raise MyException

 不建议使用

raise MyException,'Error message'
raise 'Error message'

 不要使用catch-all ,减少try/except 中代码量,使用finally.

5. Global variables

全局变量少用,如果你的变量不够全局的话

6. List comprehensions

递推式构造列表提供了一种简单有效的方法来创建lists和iterators , 但是复杂的方法会让别人难以理解。

所以写的时候要清晰,下面是两个例子:

Yes:
  result = []
  for x in range(10):
      for y in range(5):
          if x * y > 10:
              result.append((x, y))

  for x in xrange(5):
      for y in xrange(5):
          if x != y:
              for z in xrange(5):
                  if y != z:
                      yield (x, y, z)

  return ((x, complicated_transform(x))
          for x in long_generator_function(parameter)
          if x is not None)

  squares = [x * x for x in range(10)]

  eat(jelly_bean for jelly_bean in jelly_beans
      if jelly_bean.color == 'black')

No:
  result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]

  return ((x, y, z)
          for x in xrange(5)
          for y in xrange(5)
          if x != y
          for z in xrange(5)
          if y != z)

7. Default Iterators and Operations

 默认的迭代器和操作简单有效,不需要额外的方法调用,放心使用

Yes:  for key in adict: ...
      if key not in adict: ...
      if obj in alist: ...
      for line in afile: ...
      for k, v in dict.iteritems(): ...

No:   for key in adict.keys(): ...
      if not adict.has_key(key): ...
      for line in afile.readlines(): ...

8.Generators

使用 "Yields:" 比使用 "Returns:" 要好。

9. Lambda Functions and Conditional Expressions

Lambda 功能和条件表达式,如果只有一行的话,可以,多了就别用了,因为可以让你的代码比较难懂。

10. Default Argument Values

别使用变化的对象做为方法的默认参数

Yes: def foo(a, b=None):
         if b is None:
             b = []

No:  def foo(a, b=[]):
         ...
No:  def foo(a, b=time.time()):  # The time the module was loaded???
         ...
No:  def foo(a, b=FLAGS.my_thing):  # sys.argv has not yet been parsed...
         ...

11. True/False evaluations

如果可能的话使用隐式的false.

当在一个条件表达式中,Python  会自动判断值是否是为false, 一个快速的检验方法是所有的“空”是false,比如,0,None, [], {}, '' 。

这些规定比较简单,并且不容易出错,但是对c/c++开发人员来说比较奇怪。

下面是一些例子

Yes: if not users:
         print 'no users'

     if foo == 0:
         self.handle_zero()

     if i % 10 == 0:
         self.handle_multiple_of_ten()

No:  if len(users) == 0:
         print 'no users'

     if foo is not None and not foo:
         self.handle_zero()

     if not i % 10:
         self.handle_multiple_of_ten()

12. Deprecated Language Features

过期的特性就不要使用了,比如

Yes: words = foo.split(':')

     [x[1] for x in my_list if x[2] == 5]

     map(math.sqrt, data)    # Ok. No inlined lambda expression.

     fn(*args, **kwargs)

No:  words = string.split(foo, ':')

     map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))

     apply(fn, args, kwargs)

13. Lexical Scoping

词法作用域。

14. Function and Method Decorators

当有好处的时候果断使用

class C(object):
    @my_decorator
    def method(self):
        # method body ...

等价于:

class C(object):
    def method(self):
        # method body ...
    method = my_decorator(method)

15. Threading

 别依赖内建的原子类型

16. Power Features

避免使用这些。

Python 有很多神奇的特性,比如metaclasses, access to bytecode , on-the-fly comilation, dynamic inheritance, object reparenting , import hacks, reflection ,modification of system internals.

看起来很‘酷’,但是难读,难懂,难debug,少用吧。