更好的Python代码

Table of Contents

这里,逐步记录一些Python代码优化经验和想法。

1 小工具

  • flake8:检查Python代码标准
  • pep8:检查Python代码是否符合PEP8

2 减少无用变量

变量增强了表达式的可读性,但过度使用变量也会造成困扰,定义无用的中间变量是很常见的做法,如:

def this_is_a_function(a_list):
    result = False

    for i in a_list:
	if x > 0:
	    result = True
	    return result

    return result

可以简化:

def this_is_a_function(a_list):
    for i in a_list:
	if x > 0:
	    return True

    return False

有时我也会在函数中看到类似这样的代码:

info = {}
info["name"] = user.get_name()
info["age"] = user.get_age()
return info

可简化为:

return {
    "name": user.get_name(),
    "age": user.get_age()
}

3 让结构更美观一点

字段太多时,我喜欢用这样的格式来美化:

info = {
    "name": "lu4nx",
    "website": "www.shellcodes.org"
}

而不是:

info = {"name": "lu4nx", "website": "www.shellcodes.org"}

或者:

info = {"name": "lu4nx",
	"website": "www.shellcodes.org"}

甚至函数参数太多的情况下,也是,这样避免挤在一起:

db.update(
    "User",
    name="lu4nx",
    website="www.shellcodes.org",
    email="lx_at_shellcodes.org",
    ...
)

反正我是不喜欢这样的:

db.update("User", \
	  name="lu4nx", \
	  website="www.shellcodes.org", \
	  email="lx_at_shellcodes.org", \
	  ...)

4 尽早提前结束

def this_is_a_function():
    if xxx:
	...此处省略N行

    do_something

这样会更好:

def this_is_a_function():
    if not xxx:
	return

    ...此处省略N行
    do_something

5 尽量避免if..elif..

Python没有switch语法,只有if..elif,经常会在代码中看到类似:

if input_data == "a":
    return a_handler()
elif input_data == "b":
    return b_handler()
elif input_data == "c":
    return c_handler()
else:
    return default_handler()

如果判断条件太多,可用字典来简化:

handler_functions = {
    "a": a_handler,
    "b": b_handler,
    "c": c_handler
}

func = handler_functions.get(input_data)
if not func:
    return default_handler()

return func()

6 捕获Exception异常的陷阱

我在一段多线程代码里偷了个懒:

try:
    resp = http_get(url)
    lock.acquire()
    ....
    lock.realease()
except Exception:
    pass

后来死活都出现死锁问题,最后发现lock.release写成lock.realease了。但由于被异常捕获并忽略了,导致调试很久。

所以:

  1. Exception异常尽可能留在最后捕获,先捕获一些已知会发生的异常。
  2. 不要轻易捕获所有异常并且还不做任何处理,至少也该把异常记录到日志或者打印出来。