autopep8 是一个将 Python 代码自动排版为 PEP8 风格的小工具。它使用 pep8 工具来决定代码中的哪部分需要被排版。autopep8 可以修复大部分 pep8 工具中报告的排版问题。
PyCharm 使用 autopep8 按 PEP8 风格自动排版 Python 代码
2018 年 12 月 27 日 - 初稿
阅读原文 - https://wsgzao.github.io/post/autopep8/
扩展阅读
autopep8 - https://pypi.python.org/pypi/autopep8/
使用 autopep8 前我们有必要先了解下 PEP 8 -- Style Guide for Python Code
autopep8 automatically formats Python code to conform to the PEP 8 style guide. It uses the pycodestyle utility to determine what parts of the code needs to be formatted. autopep8 is capable of fixing most of the formatting issues that can be reported by pycodestyle.
https://www.python.org/dev/peps/pep-0008/
https://pypi.python.org/pypi/autopep8/
autopep8 是一个开源的命令行工具,它能够将 Python 代码自动格式化为 PEP8 风格。autopep8 使用 pycodestyle 工具来决定代码中的哪部分需要被格式化,这能够修复大部分 pycodestyle 工具中报告的排版问题。autopep8 本身也是一个 Python 语言编写的工具,因此,我们可以直接使用 pip 进行安装:
pip install autopep8
autopep8 --in-place optparse.py
# To modify a file in place (with aggressive level 2):
autopep8 --in-place --aggressive --aggressive <filename>
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] [--hang-closing] [--exit-code]
[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:
E226,E24,W50,W690)
--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
--hang-closing hang-closing option passed to pycodestyle
--exit-code change to behavior of exit code. default behavior of
return value, 0 is no differences, 1 is error exit.
return 2 when add this option. 2 is exists
differences.
--in-place 类似于 sed 命令的-i 选项,如果不包含--in-place 选项,则会将 autopep8 格式化以后的代码直接输出到控制台。我们可以使用这种方式检查 autopep8 的修改,使用--in-place 则会直接将结果保存到源文件中。
我们来看一个完整的例子,本例中使用的代码如下:
import os, sys
def main():
print [item for item in os.listdir('.') if item.endswith('.py')];
print sys.version
if __name__ == '__main__':
main()
这段代码存在三个问题:
接下来,我们将使用 pycodestyple 检查这段代码,然后使用 autopep8 将代码格式化成符合 PEP 8 风格的代码。
使用 pycodestyle 检查代码可检测到代码中有三个地方不符合 PEP 8 规范,如下所示:
pycodestyle hello.py
hello.py:1:10: E401 multiple imports on one line
hello.py:3:1: E302 expected 2 blank lines, found 1
hello.py:4:69: E703 statement ends with a semicolon
使用 autopep8 格式能够转换 Python 代码。在这个例子中,autopep8 顺利地帮我们修复了所有问题,如下所示:
$ autopep8 hello.py
import os
import sys
def main():
print [item for item in os.listdir('.') if item.endswith('.py')]
print sys.version
if __name__ == '__main__':
main()
这个时候如果查看源文件的话,会发现还是和原来一样,并没有修正为符合 PEP 8 规范的代码。前面说过,不指定--in-place 选项,只会将结果输出到命令行。如果我们使用--in-place 选项,将不会有任何输出,autopep8 会直接修改源文件。
$ autopep8 --in-place hello.py
autopep8 还存在--aggressive 选项,使用该选项会执行更多实质性的更改,可以多次使用以达到更佳的效果。
以官网为例我们编写一个 test_autopep8.py
Before running autopep8.
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)
After running autopep8.
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)
autopep8 fixes the following issues reported by pycodestyle:
https://github.com/PyCQA/pycodestyle
E101 - Reindent all lines.
E11 - Fix indentation.
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.
E129 - Fix visual indentation.
E131 - Fix hanging indent for unaligned continuation line.
E133 - Fix missing indentation for closing bracket.
E20 - Remove extraneous whitespace.
E211 - Remove extraneous whitespace.
E22 - Fix extraneous whitespace around keywords.
E224 - Remove extraneous whitespace around operator.
E225 - Fix missing 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.
E252 - Missing whitespace around parameter equals.
E26 - Fix spacing after comment hash for inline comments.
E265 - Fix spacing after comment hash for block comments.
E266 - Fix too many leading '#' 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.
E305 - Expected 2 blank lines after end of function or class.
E306 - Expected 1 blank line before a nested definition.
E401 - Put imports on separate lines.
E402 - Fix module level import not at top of file
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.
E713 - Use 'not in' for test for membership.
E714 - Use 'is not' test for object identity.
E721 - Use "isinstance()" instead of comparing types directly.
E722 - Fix bare except.
E731 - Use a def when use do not assign a lambda expression.
W291 - Remove trailing whitespace.
W292 - Add a single newline at the end of the file.
W293 - Remove trailing whitespace on blank line.
W391 - Remove trailing blank lines.
W503 - Fix line break before binary operator.
W504 - Fix line break after binary operator.
W601 - Use "in" rather than "has_key()".
W602 - Fix deprecated form of raising exception.
W603 - Use "!=" instead of "<>"
W604 - Use "repr()" instead of backticks.
W605 - Fix invalid escape sequence 'x'.
W690 - Fix various deprecated code (via lib2to3).
pip 安装 autopep8: pip install autopep8
PyCharm -> Preferences -> Tools -> Extends Tools -> 点击+加号
Name: autopep8 Tools settings:
autopep8
--in-place --aggressive --aggressive $FilePath$
$ProjectFileDir$
$FILE_PATH$\:$LINE$\:$COLUMN$\:.*
最后以 Python 之禅作为结束语
wangao@wangao-MAC ~ python3
Python 3.7.1 (default, Nov 6 2018, 18:46:03)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
翻译
美 优于 丑
明确 优于 隐晦 ( 1 )
简单 优于 复杂
复杂 也好过 繁复 ( 2 )
扁平 优于 嵌套
稀疏 优于 拥挤
可读性很重要( 3 )
固然代码实用与否 比洁癖更重要,
我们以为的特例也往往没有特殊到必须打破上述规则的程度
除非刻意地静默,
否则不要无故忽视异常( 4 )
如果遇到模棱两可的逻辑,请不要自作聪明地瞎猜。
应该提供一种,且最好只提供一种,一目了然的解决方案
当然这是没法一蹴而就的,除非你是荷兰人( 5 )
固然,立刻着手 好过 永远不做。
然而,永远不做 也好过 不审慎思考一撸袖子就莽着干
如果你的实现很难解释,它就一定不是个好主意
即使你的实现简单到爆,它也有可能是个好办法
命名空间大法好,不搞不是地球人!
注释
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.