本文记录了一些笔者在使用 python[如无特别说明,主要是 python3]的技巧或者需要注意的地方,其他 python 的主要特性或者重要的使用方式,会单独成文不会列在这里。本文会持续更新。

Main Function

python 程序的入口应该使用下面的方法,因为这种方式,可以清晰的表达此 python 程序存在程序入口可以被执行。而且额外定义 main()方法,可以更加清晰的管理变量作用域,因为在if __name__ == '__main__':中的变量一般是全局变量。

def main():
    ...

if __name__ == '__main__':
    main()

Numpy Performance

python 并不是一个效率至上的编程语言,所以有些时候需要考虑更加高效的第三方库,比如 numpy,numba 等等。numpy 的核心计算实现是通过 C 语言实现,所以比 python 自带的一些方法更快。比如下面的求和函数,numpy 实现比 python 自带函数快 10 倍左右。

def sum(n=100000000):
    return sum(range(n))

def sum_numpy(n=100000000):
    return numpy.sum(numpy.arange(n))

f string

python 从 3.6 开始中新增了f string的特性,用来取代str.format(),主要可以解决后者的长度的问题。f string可以在 debug 中快速的打印变量名称和值

num_value = 123
print(f'the value is {num_value}')
# print: the value is 123
print(f'{num_value = }')
# print: num_value = 123

Decorator

@cache是一个非常有用的装饰器[Decorator],它会保存已经计算过的结果,如果未来再次出现相同计算则可以直接返回结果。这种方式对于递归计算非常有用,比如计算fibonacci sequence。类似的装饰器还有@lru_cache

@cache
def fib(n):
    if n<= 1:
        return n
    return fib(n-1) + fib(n-2)

#!/usr/bin/env python3

很多 python 文件的开头第一行都是#!/usr/bin/env python3,这个语法是在通过chmod +x的方式将 python 文件转换成可执行文件的时候,定义自动寻找 python 解释其的路径。其实也可以定义绝对路径,但是因为笔者都是在 python 虚拟环境下开发,所以#!/usr/bin/env python3这种写法允许程序自动获得当前使用的 python 解释器。

Interpreter Path

在 python 程序中想要得知当前 python 解释器的路径,可以使用import sys; print(sys.executable)。虽然平时写 python 中几乎不用”分号”,但是它可以分隔写在一行里的多条语句。

pylint, pretty-errors, flake8

pylint可以对代码风格进行检查,代码书写规范在团队合作时尤为重要。 pretty-errors工具可以优化 python 的 error output。考虑到 python 原生的 error output 非常不友好,pretty-errors 对 debug 非常有用了。 flake8是一个将 PEP 8、Pyflakes、McCabe[代码复杂性检查器]和第三方插件整合到一起的代码检查工具。

pip install pylint
pip install pretty-errors
pip install flake8

pip freeze

pip freeze命令可以根据当前环境自动生成requirements.txt[Output installed packages in requirements format]。

read with size

Python 读取大文件时,可以通过对read设置读取size的方式来避免一次性读取过大文件造成内存溢出。

with open(file_name, encoding='utf-8') as file_obj:
    file_content = ''
    chunk = 200

    while True:
        content = file_obj.read(chunk)

        if not content:
            break

        print(content, end='')

time.perf_counter()

在python中,经常要计算程序执行的时间,一般都是使用time.time()的方式记录当前时间,然后计算差值。自从python3.3之后,time引入了perf_counter()方法,它能够更加准确的计算程序执行时间

import time

def timing_with_time():
    start = time.perf_counter()
    time.sleep(1)
    end = time.perf_counter()
    print(end - start) 

logging

在程序运行过程中如果需要输出中间结果的时候可以使用logging库,贴一个官方的代码例子

import logging

# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')