python 代码格式化工具:autopep8

时间:2023-03-08 17:32:59
python 代码格式化工具:autopep8

学习资料: 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 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
-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: )
--line-range line line, --range line line
only fix errors found within this inclusive range of
line numbers (e.g. ); line numbers are indexed at

特性

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 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'