如何优雅的阅读 Python 代码

无论是接手同事的祖传代码还是学习优秀开源项目,都需要阅读代码,简单粗暴的 vim foo.py当然可以,但更好的方式是提前做好充足的准备,下面是我日常的一些技巧:

1.格式化代码
每个人的编程风格迥异,不一定符合 pep8规范,阅读前先将代码格式化能够带来赏心悦目的阅读体验;如下是一坨代码风格很差的代码:

import math, sys;

def example1():
    ####This is a long comment. This should be wrapped to fit within 72 characters.
    some_tuple=(   1,2, 3,'a'  );
    some_variable={'long':'Long code lines should be wrapped within 79 characters.',
    'other':[math.pi, 100,200,300,9876543210,'This is a long string that goes on'],
    'more':{'inner':'This whole logical line should be wrapped.',some_tuple:[1,
    20,300,40000,500000000,60000000000000000]}}
    return (some_tuple, some_variable)
def example2(): return {'has_key() is deprecated':True}.has_key({'f':2}.has_key(''));
class Example3(   object ):
    def __init__    ( self, bar ):
     #Comments should have a space after the hash.
     if bar : bar+=1;  bar=bar* bar   ; return bar
     else:
                    some_string = """
                       Indentation in multiline strings should not be touched.
Only actual code should be reindented.
"""
                    return (sys.path, some_string)

格式化后

import math
import sys

def example1():
    # This is a long comment. This should be wrapped to fit within 72
    # characters.
    some_tuple = (1, 2, 3, 'a')
    some_variable = {
        'long': 'Long code lines should be wrapped within 79 characters.',
        'other': [
            math.pi,
            100,
            200,
            300,
            9876543210,
            'This is a long string that goes on'],
        'more': {
            'inner': 'This whole logical line should be wrapped.',
            some_tuple: [
                1,
                20,
                300,
                40000,
                500000000,
                60000000000000000]}}
    return (some_tuple, some_variable)

def example2():
    return ('' in {'f': 2}) in {'has_key() is deprecated': True}

class Example3(object):

    def __init__(self, bar):
        # Comments should have a space after the hash.
        if bar:
            bar += 1
            bar = bar * bar
            return bar
        else:
            some_string = """
                       Indentation in multiline strings should not be touched.
Only actual code should be reindented.
"""
            return (sys.path, some_string)

赏心悦目多了吧~
社区有很多格式化工具,如:pylint、yapf、autopep8等

2.自动生成类型注解
静态语言更易后期团队维护的一个原因是变量定义时就指定了类型,Python 3.6之后类型注解功能稍微补足了这方面;而Facebook 的Instagram 团队开源的 MonkeyType 这个工具能对现有的代码自动生成类型注解,是个大神器~
一个普通不过的函数定义

def add(a, b):
    return a + b

自动生成类型注解后

def add(a: int, b: int) -> int:
    return a + b

3.静态检查
有了类型注解后就可以在不运行程序的情况下进行静态检查及时发现错误了,譬如下面这段程序, fib 函数应该接受整型,但不小心传了字符串:

from typing import Iterator

def fib(n: int) -> Iterator[int]:
    a, b = 0, 1
    while a < n:
        yield a
        a, b = b, a + b

print(fib('4'))

运行静态检查工具 mypy 就可以提前发现错误了:


图片.png

4.找一个好的代码阅读器
这方面好的编辑器就已经是非常优秀的阅读器了,代码高亮、定义跳转等都是标配了;
SpaceVim、VS Code、PyCharm、Sublime Text都是业内有口皆碑的产品


图片.png

5.更美观的异常提示
代码运行可能会报异常,better-exceptions这个工具能产生比默认更美观的异常提示:

图片.png

6.官方手册随身带
阅读代码过程中可能遇到个自己不太熟悉函数名或语法,这时候再谷歌就太没效率了,Alfred+Dash(或 devdocs)能将官方手册随时调用出来查询


图片.png