學習資料: https://github.com/hhatto/autopep8
背景
autopep8 會根據 PEP 8 樣式文件來格式化 python 程式碼。它使用 pep8 來決定程式碼的哪部分需要被格式化。 autopep8 可以修復 pep8彙報的大部分格式問題。
PEP8 是 Python Enhancement Proposal 的縮寫,翻譯過來就是 python 增強建議書, 是python的一個官方樣式指導。它規定了一些比較好的編碼方式,比如用4個空格代替縮排等等。
PEP 0008 -- Style Guide for Python Code: https://www.python.org/dev/peps/pep-0008/
安裝
$ pip install --upgrade autopep8
用法
usage: autopep8 [-h] [--version] [-v] [-d] [-i] [--global-config filename] [--ignore-local-config] [-r] [-j n] [-p n] [-a] [--experimental] [--exclude globs] [--list-fixes] [--ignore errors] [--select errors] [--max-line-length n] [--line-range line line] [files [files ...]] Automatically formats Python code to conform to the PEP 8 style guide. positional arguments: files files to format or '-' for standard in optional arguments: -h, --help show this help message and exit --version show program's version number and exit -v, --verbose print verbose messages; multiple -v result in more verbose messages -d, --diff print the diff for the fixed source -i, --in-place make changes to files in place --global-config filename path to a global pep8 config file; if this file does not exist then this is ignored (default: ~/.config/pep8) --ignore-local-config don't look for and apply local config files; if not passed, defaults are updated with any config files in the project's root directory -r, --recursive run recursively over directories; must be used with --in-place or --diff -j n, --jobs n number of parallel jobs; match CPU count if value is less than 1 -p n, --pep8-passes n maximum number of additional pep8 passes (default: infinite) -a, --aggressive enable non-whitespace changes; multiple -a result in more aggressive changes --experimental enable experimental fixes --exclude globs exclude file/directory names that match these comma- separated globs --list-fixes list codes for fixes; used by --ignore and --select --ignore errors do not fix these errors/warnings (default: E24) --select errors fix only these errors/warnings (e.g. E4,W) --max-line-length n set maximum allowed line length (default: 79) --line-range line line, --range line line only fix errors found within this inclusive range of line numbers (e.g. 1 99); line numbers are indexed at 1
特性
autopep8會修復pep8彙報的下列問題:
E101 - Reindent all lines. E121 - Fix indentation to be a multiple of four. E122 - Add absent indentation for hanging indentation. E123 - Align closing bracket to match opening bracket. E124 - Align closing bracket to match visual indentation. E125 - Indent to distinguish line from next logical line. E126 - Fix over-indented hanging indentation. E127 - Fix visual indentation. E128 - Fix visual indentation. E20 - Remove extraneous whitespace. E211 - Remove extraneous whitespace. E22 - Fix extraneous whitespace around keywords. E224 - Remove extraneous whitespace around operator. E226 - Fix missing whitespace around arithmetic operator. E227 - Fix missing whitespace around bitwise/shift operator. E228 - Fix missing whitespace around modulo operator. E231 - Add missing whitespace. E241 - Fix extraneous whitespace around keywords. E242 - Remove extraneous whitespace around operator. E251 - Remove whitespace around parameter '=' sign. E26 - Fix spacing after comment hash for inline comments. E265 - Fix spacing after comment hash for block comments. E27 - Fix extraneous whitespace around keywords. E301 - Add missing blank line. E302 - Add missing 2 blank lines. E303 - Remove extra blank lines. E304 - Remove blank line following function decorator. E309 - Add missing blank line (after class declaration). E401 - Put imports on separate lines. E501 - Try to make lines fit within --max-line-length characters. E502 - Remove extraneous escape of newline. E701 - Put colon-separated compound statement on separate lines. E70 - Put semicolon-separated compound statement on separate lines. E711 - Fix comparison with None. E712 - Fix comparison with boolean. E721 - Use "isinstance()" instead of comparing types directly. W291 - Remove trailing whitespace. W293 - Remove trailing whitespace on blank line. W391 - Remove trailing blank lines. W601 - Use "in" rather than "has_key()". W602 - Fix deprecated form of raising exception. W603 - Use "!=" instead of "<>" W604 - Use "repr()" instead of backticks. W690 - Fix various deprecated code (via lib2to3).
備註:
autopep8 也會忽略一些 pep8 的問題。
1. E112/E113
2. E265
autopep8 也會修復一個非pep8彙報的問題:
1. 糾正棄用的以及非慣用的python程式碼(通過 lib2to3)。這會讓python 2.6 以及 python 2.7 的程式碼更加與 python3 相容。(如果 W690 是enable的,這一項修復會被觸發)
2. 標準化具有多種行結束符的檔案。
3. 在類申明和它的第一個方法申明中間加一個空行。(由 E309 enable)
4. 在類文件和它的第一個方法申明中間加一個空行。(由 E301 enable)
5. 移除方法申明和它的文件之間的空行。 (由 E303 enable )
具體用法
1. 使用 autopep8 更改一個檔案。
假設檔名是 a.py,檔案內容如下:
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)
轉到 Python3\Scripts 路徑,可以看到 autopep8.exe 檔案。
在a.py路徑下,開啟cmd,執行下列命令:
D:\Python3\Scripts\autopep8 --in-place --aggressive --aggressive a.py
備註:
--in-place: 以更改後的檔案直接替代原始檔。
--aggressive --aggressive : 以 aggressive 等級2 來更改原始檔。
更改之後,a.py內容如下:
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)
2. aggressive 等級
預設情況下,autopep8只修復空格問題。所以,預設情況下,autopep8不會修復 E711 和 E712 ,也不會修復棄用的程式碼 W6。
為了應用這些更加 aggressive 的修復,使用 --aggressive 選項:
autopep8 --aggressive a.py
使用多個 --aggressive 可以增加 aggressiveness 等級。
比如, E712 需要 aggressiveness 等級2.
autopep8 --aggressive --aggressive a.py
3. 選擇修復部分規範
只修復一部分規範,使用 --select 選項。
比如,修復多種縮排問題:
$ autopep8 --select=E1,W1 a.py
僅僅修復棄用程式碼問題:
$ autopep8 --aggressive --select=W6 a.py
4. 顯示詳細的過程資訊
$ autopep8 -v a.py
5. 以模組的方式使用
>>> import autopep8 >>> autopep8.fix_code('x= 123\n') 'x = 123\n'
6. 以模組的方式使用,且帶有條件
>>> import autopep8 >>> autopep8.fix_code('x.has_key(y)\n', options={'aggressive': 1}) 'y in x\n' >>> autopep8.fix_code('print( 123 )\n', options={'ignore': ['E']}) 'print( 123 )\n'