2.3.1 避免bugs

2.3.1.1 避免麻烦的最佳代码实践

Brian Kernighan

“每个人都知道除错比从零开始写一个程序难两倍。因此,如果当你写程序时足够聪明,为什么你不对它进行除错呢?”

  • 我都会写出有错误的代码。接收这些代码。处理这些代码。
  • 写代码时记得测试和除错。
  • 保持简单和直接(KISS)。
    • 能起作用的最简单的事是什么?
  • 不要重复自身(DRY)。
    • 每一个知识碎片都必须在系统中有一个清晰、权威的表征
    • 变量、算法等等
  • 试着限制代码的依赖。(松耦合)
  • 给变量、函数和模块有意义的名字(而不是数学名字)

2.3.1.2 pyflakes:快速静态分析

在Python中有一些静态分析;举几个例子:

这里我们关注pyflakes,它是最简单的工具。

  • 快速简单
  • 识别语法错误、没有imports、名字打印打错。

另一个好的推荐是flake8工具,是pyflakes和pep8。因此,除了pyflakes捕捉错误类型外,flake8也可以察觉对PEP8风格指南建议的违背。

强烈推荐在你的编辑器或IDE整合pyflakes (或 flake8),确实可以产出生产力的收益

2.3.1.2.1 在当前编辑文件上运行pyflakes

你可以在当前缓存器中绑定一个键来运行pyflakes。

  • 在kate中
    • 菜单:设定 -> 配置 kate
    • 在插件中启用“外部”
    • 在外部工具,添加pyflakes:

In [ ]:

  1. kdialog --title "pyflakes %filename" --msgbox "$(pyflakes %filename)"
  • 在TextMate中
    • 菜单: TextMate -> 偏好 -> 高级 -> Shell变量,添加shell变量:

In [ ]:

  1. TM_PYCHECKER=/Library/Frameworks/Python.framework/Versions/Current/bin/pyflakes
  1. - 然后 Ctrl-Shift-V 被绑定到pyflakes报告
  • 在vim中
    • 在你的vimrc中 (将F5绑定到pyflakes):

In [ ]:

  1. autocmd FileType python let &mp = 'echo "*** running % ***" ; pyflakes %'
  2. autocmd FileType tex,mp,rst,python imap <Esc>[15~ <C-O>:make!^M
  3. autocmd FileType tex,mp,rst,python map <Esc>[15~ :make!^M
  4. autocmd FileType tex,mp,rst,python set autowrite
  • 在emacs中
    • 在你的emacs中 (将F5绑定到pyflakes):

In [ ]:

  1. (defun pyflakes-thisfile () (interactive)
  2. (compile (format "pyflakes %s" (buffer-file-name)))
  3. )
  4. (define-minor-mode pyflakes-mode
  5. "Toggle pyflakes mode.
  6. With no argument, this command toggles the mode.
  7. Non-null prefix argument turns on the mode.
  8. Null prefix argument turns off the mode."
  9. ;; The initial value.
  10. nil
  11. ;; The indicator for the mode line.
  12. " Pyflakes"
  13. ;; The minor mode bindings.
  14. '( ([f5] . pyflakes-thisfile) )
  15. )
  16. (add-hook 'python-mode-hook (lambda () (pyflakes-mode t)))

2.3.1.2.2 随着打字进行的拼写检查器整合

In [ ]:

  1. (when (load "flymake" t)
  2. (defun flymake-pyflakes-init ()
  3. (let* ((temp-file (flymake-init-create-temp-buffer-copy
  4. 'flymake-create-temp-inplace))
  5. (local-file (file-relative-name
  6. temp-file
  7. (file-name-directory buffer-file-name))))
  8. (list "pyflakes" (list local-file))))
  9. (add-to-list 'flymake-allowed-file-name-masks
  10. '("\\.py\\'" flymake-pyflakes-init)))
  11. (add-hook 'find-file-hook 'flymake-find-file-hook)