Меню

Проверить код на ошибки pep8

pep8 — Python style guide checker

pep8 is a tool to check your Python code against some of the style
conventions in PEP 8.

Features

  • Plugin architecture: Adding new checks is easy.

  • Parseable output: Jump to error location in your editor.

  • Small: Just one Python file, requires only stdlib. You can use just
    the pep8.py file for this purpose.

  • Comes with a comprehensive test suite.

Installation

You can install, upgrade, uninstall pep8.py with these commands:

$ pip install pep8
$ pip install --upgrade pep8
$ pip uninstall pep8

There’s also a package for Debian/Ubuntu, but it’s not always the
latest version.

Example usage and output

$ pep8 --first optparse.py
optparse.py:69:11: E401 multiple imports on one line
optparse.py:77:1: E302 expected 2 blank lines, found 1
optparse.py:88:5: E301 expected 1 blank line, found 0
optparse.py:222:34: W602 deprecated form of raising exception
optparse.py:347:31: E211 whitespace before '('
optparse.py:357:17: E201 whitespace after '{'
optparse.py:472:29: E221 multiple spaces before operator
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'

You can also make pep8.py show the source code for each error, and
even the relevant text from PEP 8:

$ pep8 --show-source --show-pep8 testsuite/E40.py
testsuite/E40.py:2:10: E401 multiple imports on one line
import os, sys
         ^
    Imports should usually be on separate lines.

    Okay: import osnimport sys
    E401: import sys, os

Or you can display how often each error was found:

$ pep8 --statistics -qq Python-2.5/Lib
232     E201 whitespace after '['
599     E202 whitespace before ')'
631     E203 whitespace before ','
842     E211 whitespace before '('
2531    E221 multiple spaces before operator
4473    E301 expected 1 blank line, found 0
4006    E302 expected 2 blank lines, found 1
165     E303 too many blank lines (4)
325     E401 multiple imports on one line
3615    E501 line too long (82 characters)
612     W601 .has_key() is deprecated, use 'in'
1188    W602 deprecated form of raising exception

Links

Build status
Wheel Status

  • Read the documentation

  • Fork me on GitHub

Changelog

1.7.1 (2017-10-22)

Changes:

  • Prominently note via warning message that the tool is no longer released as
    pep8 and will only be fixed in the pycodestyle package

1.7.0 (2016-01-12)

Announcements:

  • Repository moved to PyCQA Organization on GitHub:
    https://github.com/pycqa/pep8

Changes:

  • Reverted the fix in #368, “options passed on command line are only ones
    accepted” feature. This has many unintended consequences in pep8 and flake8
    and needs to be reworked when I have more time.

  • Added support for Python 3.5. (Issue #420 & #459)

  • Added support for multi-line config_file option parsing. (Issue #429)

  • Improved parameter parsing. (Issues #420 & #456)

Bugs:

  • Fixed BytesWarning on Python 3. (Issue #459)

1.6.2 (2015-02-15)

Changes:

  • Added check for breaking around a binary operator. (Issue #197, Pull #305)

Bugs:

  • Restored config_file parameter in process_options(). (Issue #380)

1.6.1 (2015-02-08)

Changes:

  • Assign variables before referenced. (Issue #287)

Bugs:

  • Exception thrown due to unassigned local_dir variable. (Issue #377)

1.6.0 (2015-02-06)

News:

  • Ian Lee <ianlee1521@gmail.com> joined the project as a maintainer.

Changes:

  • Report E731 for lambda assignment. (Issue #277)

  • Report E704 for one-liner def instead of E701.
    Do not report this error in the default configuration. (Issue #277)

  • Replace codes E111, E112 and E113 with codes E114, E115 and E116
    for bad indentation of comments. (Issue #274)

  • Report E266 instead of E265 when the block comment starts with
    multiple #. (Issue #270)

  • Report E402 for import statements not at the top of the file. (Issue #264)

  • Do not enforce whitespaces around ** operator. (Issue #292)

  • Strip whitespace from around paths during normalization. (Issue #339 / #343)

  • Update —format documentation. (Issue #198 / Pull Request #310)

  • Add .tox/ to default excludes. (Issue #335)

  • Do not report E121 or E126 in the default configuration. (Issues #256 / #316)

  • Allow spaces around the equals sign in an annotated function. (Issue #357)

  • Allow trailing backslash if in an inline comment. (Issue #374)

  • If —config is used, only that configuration is processed. Otherwise,
    merge the user and local configurations are merged. (Issue #368 / #369)

Bug fixes:

  • Don’t crash if Checker.build_tokens_line() returns None. (Issue #306)

  • Don’t crash if os.path.expanduser() throws an ImportError. (Issue #297)

  • Missing space around keyword parameter equal not always reported, E251.
    (Issue #323)

  • Fix false positive E711/E712/E713. (Issues #330 and #336)

  • Do not skip physical checks if the newline is escaped. (Issue #319)

  • Flush sys.stdout to avoid race conditions with printing. See flake8 bug:
    https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363)

1.5.7 (2014-05-29)

Bug fixes:

  • Skip the traceback on “Broken pipe” signal. (Issue #275)

  • Do not exit when an option in setup.cfg or tox.ini
    is not recognized.

  • Check the last line even if it does not end with a newline. (Issue #286)

  • Always open files in universal newlines mode in Python 2. (Issue #288)

1.5.6 (2014-04-14)

Bug fixes:

  • Check the last line even if it has no end-of-line. (Issue #273)

1.5.5 (2014-04-10)

Bug fixes:

  • Fix regression with E22 checks and inline comments. (Issue #271)

1.5.4 (2014-04-07)

Bug fixes:

  • Fix negative offset with E303 before a multi-line docstring.
    (Issue #269)

1.5.3 (2014-04-04)

Bug fixes:

  • Fix wrong offset computation when error is on the last char
    of a physical line. (Issue #268)

1.5.2 (2014-04-04)

Changes:

  • Distribute a universal wheel file.

Bug fixes:

  • Report correct line number for E303 with comments. (Issue #60)

  • Do not allow newline after parameter equal. (Issue #252)

  • Fix line number reported for multi-line strings. (Issue #220)

  • Fix false positive E121/E126 with multi-line strings. (Issue #265)

  • Fix E501 not detected in comments with Python 2.5.

  • Fix caret position with —show-source when line contains tabs.

1.5.1 (2014-03-27)

Bug fixes:

  • Fix a crash with E125 on multi-line strings. (Issue #263)

1.5 (2014-03-26)

Changes:

  • Report E129 instead of E125 for visually indented line with same
    indent as next logical line. (Issue #126)

  • Report E265 for space before block comment. (Issue #190)

  • Report E713 and E714 when operators not in and is not are
    recommended. (Issue #236)

  • Allow long lines in multiline strings and comments if they cannot
    be wrapped. (Issue #224).

  • Optionally disable physical line checks inside multiline strings,
    using # noqa. (Issue #242)

  • Change text for E121 to report “continuation line under-indented
    for hanging indent” instead of indentation not being a
    multiple of 4.

  • Report E131 instead of E121 / E126 if the hanging indent is not
    consistent within the same continuation block. It helps when
    error E121 or E126 is in the ignore list.

  • Report E126 instead of E121 when the continuation line is hanging
    with extra indentation, even if indentation is not a multiple of 4.

Bug fixes:

  • Allow the checkers to report errors on empty files. (Issue #240)

  • Fix ignoring too many checks when —select is used with codes
    declared in a flake8 extension. (Issue #216)

  • Fix regression with multiple brackets. (Issue #214)

  • Fix StyleGuide to parse the local configuration if the
    keyword argument paths is specified. (Issue #246)

  • Fix a false positive E124 for hanging indent. (Issue #254)

  • Fix a false positive E126 with embedded colon. (Issue #144)

  • Fix a false positive E126 when indenting with tabs. (Issue #204)

  • Fix behaviour when exclude is in the configuration file and
    the current directory is not the project directory. (Issue #247)

  • The logical checks can return None instead of an empty iterator.
    (Issue #250)

  • Do not report multiple E101 if only the first indentation starts
    with a tab. (Issue #237)

  • Fix a rare false positive W602. (Issue #34)

1.4.6 (2013-07-02)

Changes:

  • Honor # noqa for errors E711 and E712. (Issue #180)

  • When both a tox.ini and a setup.cfg are present in the project
    directory, merge their contents. The tox.ini file takes
    precedence (same as before). (Issue #182)

  • Give priority to —select over —ignore. (Issue #188)

  • Compare full path when excluding a file. (Issue #186)

  • New option —hang-closing to switch to the alternative style of
    closing bracket indentation for hanging indent. Add error E133 for
    closing bracket which is missing indentation. (Issue #103)

  • Accept both styles of closing bracket indentation for hanging indent.
    Do not report error E123 in the default configuration. (Issue #103)

Bug fixes:

  • Do not crash when running AST checks and the document contains null bytes.
    (Issue #184)

  • Correctly report other E12 errors when E123 is ignored. (Issue #103)

  • Fix false positive E261/E262 when the file contains a BOM. (Issue #193)

  • Fix E701, E702 and E703 not detected sometimes. (Issue #196)

  • Fix E122 not detected in some cases. (Issue #201 and #208)

  • Fix false positive E121 with multiple brackets. (Issue #203)

1.4.5 (2013-03-06)

  • When no path is specified, do not try to read from stdin. The feature
    was added in 1.4.3, but it is not supported on Windows. Use
    filename argument to read from stdin. This usage is supported
    since 1.3.4. (Issue #170)

  • Do not require setuptools in setup.py. It works around an issue
    with pip and Python 3. (Issue #172)

  • Add __pycache__ to the ignore list.

  • Change misleading message for E251. (Issue #171)

  • Do not report false E302 when the source file has a coding cookie or a
    comment on the first line. (Issue #174)

  • Reorganize the tests and add tests for the API and for the command line
    usage and options. (Issues #161 and #162)

  • Ignore all checks which are not explicitly selected when select is
    passed to the StyleGuide constructor.

1.4.4 (2013-02-24)

  • Report E227 or E228 instead of E225 for whitespace around bitwise, shift
    or modulo operators. (Issue #166)

  • Change the message for E226 to make clear that it is about arithmetic
    operators.

  • Fix a false positive E128 for continuation line indentation with tabs.

  • Fix regression with the —diff option. (Issue #169)

  • Fix the TestReport class to print the unexpected warnings and
    errors.

1.4.3 (2013-02-22)

  • Hide the —doctest and —testsuite options when installed.

  • Fix crash with AST checkers when the syntax is invalid. (Issue #160)

  • Read from standard input if no path is specified.

  • Initiate a graceful shutdown on Control+C.

  • Allow to change the checker_class for the StyleGuide.

1.4.2 (2013-02-10)

  • Support AST checkers provided by third-party applications.

  • Register new checkers with register_check(func_or_cls, codes).

  • Allow to construct a StyleGuide with a custom parser.

  • Accept visual indentation without parenthesis after the if
    statement. (Issue #151)

  • Fix UnboundLocalError when using # noqa with continued lines.
    (Issue #158)

  • Re-order the lines for the StandardReport.

  • Expand tabs when checking E12 continuation lines. (Issue #155)

  • Refactor the testing class TestReport and the specific test
    functions into a separate test module.

1.4.1 (2013-01-18)

  • Allow sphinx.ext.autodoc syntax for comments. (Issue #110)

  • Report E703 instead of E702 for the trailing semicolon. (Issue #117)

  • Honor # noqa in addition to # nopep8. (Issue #149)

  • Expose the OptionParser factory for better extensibility.

1.4 (2012-12-22)

  • Report E226 instead of E225 for optional whitespace around common
    operators (*, **, /, + and ). This new error
    code is ignored in the default configuration because PEP 8 recommends
    to “use your own judgement”. (Issue #96)

  • Lines with a # nopep8 at the end will not issue errors on line
    length E501 or continuation line indentation E12*. (Issue #27)

  • Fix AssertionError when the source file contains an invalid line
    ending «rrn». (Issue #119)

  • Read the [pep8] section of tox.ini or setup.cfg if present.
    (Issue #93 and #141)

  • Add the Sphinx-based documentation, and publish it
    on http://pep8.readthedocs.org/. (Issue #105)

1.3.4 (2012-12-18)

  • Fix false positive E124 and E128 with comments. (Issue #100)

  • Fix error on stdin when running with bpython. (Issue #101)

  • Fix false positive E401. (Issue #104)

  • Report E231 for nested dictionary in list. (Issue #142)

  • Catch E271 at the beginning of the line. (Issue #133)

  • Fix false positive E126 for multi-line comments. (Issue #138)

  • Fix false positive E221 when operator is preceded by a comma. (Issue #135)

  • Fix —diff failing on one-line hunk. (Issue #137)

  • Fix the —exclude switch for directory paths. (Issue #111)

  • Use filename to read from standard input. (Issue #128)

1.3.3 (2012-06-27)

  • Fix regression with continuation line checker. (Issue #98)

1.3.2 (2012-06-26)

  • Revert to the previous behaviour for —show-pep8:
    do not imply —first. (Issue #89)

  • Add E902 for IO errors. (Issue #87)

  • Fix false positive for E121, and missed E124. (Issue #92)

  • Set a sensible default path for config file on Windows. (Issue #95)

  • Allow verbose in the configuration file. (Issue #91)

  • Show the enforced max-line-length in the error message. (Issue #86)

1.3.1 (2012-06-18)

  • Explain which configuration options are expected. Accept and recommend
    the options names with hyphen instead of underscore. (Issue #82)

  • Do not read the user configuration when used as a module
    (except if config_file=True is passed to the StyleGuide constructor).

  • Fix wrong or missing cases for the E12 series.

  • Fix cases where E122 was missed. (Issue #81)

1.3 (2012-06-15)

  • Remove global configuration and refactor the library around
    a StyleGuide class; add the ability to configure various
    reporters. (Issue #35 and #66)

  • Read user configuration from ~/.config/pep8
    and local configuration from ./.pep8. (Issue #22)

  • Fix E502 for backslash embedded in multi-line string. (Issue #68)

  • Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72)

  • Enable the new checkers from the E12 series in the default
    configuration.

  • Suggest less error-prone alternatives for E712 errors.

  • Rewrite checkers to run faster (E22, E251, E27).

  • Fixed a crash when parsed code is invalid (too many
    closing brackets).

  • Fix E127 and E128 for continuation line indentation. (Issue #74)

  • New option —format to customize the error format. (Issue #23)

  • New option —diff to check only modified code. The unified
    diff is read from STDIN. Example: hg diff | pep8 —diff
    (Issue #39)

  • Correctly report the count of failures and set the exit code to 1
    when the —doctest or the —testsuite fails.

  • Correctly detect the encoding in Python 3. (Issue #69)

  • Drop support for Python 2.3, 2.4 and 3.0. (Issue #78)

1.2 (2012-06-01)

  • Add E121 through E128 for continuation line indentation. These
    checks are disabled by default. If you want to force all checks,
    use switch —select=E,W. Patch by Sam Vilain. (Issue #64)

  • Add E721 for direct type comparisons. (Issue #47)

  • Add E711 and E712 for comparisons to singletons. (Issue #46)

  • Fix spurious E225 and E701 for function annotations. (Issue #29)

  • Add E502 for explicit line join between brackets.

  • Fix E901 when printing source with —show-source.

  • Report all errors for each checker, instead of reporting only the
    first occurrence for each line.

  • Option —show-pep8 implies —first.

1.1 (2012-05-24)

  • Add E901 for syntax errors. (Issues #63 and #30)

  • Add E271, E272, E273 and E274 for extraneous whitespace around
    keywords. (Issue #57)

  • Add tox.ini configuration file for tests. (Issue #61)

  • Add .travis.yml configuration file for continuous integration.
    (Issue #62)

1.0.1 (2012-04-06)

  • Fix inconsistent version numbers.

1.0 (2012-04-04)

  • Fix W602 raise to handle multi-char names. (Issue #53)

0.7.0 (2012-03-26)

  • Now —first prints only the first occurrence of each error.
    The —repeat flag becomes obsolete because it is the default
    behaviour. (Issue #6)

  • Allow to specify —max-line-length. (Issue #36)

  • Make the shebang more flexible. (Issue #26)

  • Add testsuite to the bundle. (Issue #25)

  • Fixes for Jython. (Issue #49)

  • Add PyPI classifiers. (Issue #43)

  • Fix the —exclude option. (Issue #48)

  • Fix W602, accept raise with 3 arguments. (Issue #34)

  • Correctly select all tests if DEFAULT_IGNORE == ».

0.6.1 (2010-10-03)

  • Fix inconsistent version numbers. (Issue #21)

0.6.0 (2010-09-19)

  • Test suite reorganized and enhanced in order to check more failures
    with fewer test files. Read the run_tests docstring for details
    about the syntax.

  • Fix E225: accept print >>sys.stderr, «…» syntax.

  • Fix E501 for lines containing multibyte encoded characters. (Issue #7)

  • Fix E221, E222, E223, E224 not detected in some cases. (Issue #16)

  • Fix E211 to reject v = dic[‘a’] [‘b’]. (Issue #17)

  • Exit code is always 1 if any error or warning is found. (Issue #10)

  • —ignore checks are now really ignored, especially in
    conjunction with —count. (Issue #8)

  • Blank lines with spaces yield W293 instead of W291: some developers
    want to ignore this warning and indent the blank lines to paste their
    code easily in the Python interpreter.

  • Fix E301: do not require a blank line before an indented block. (Issue #14)

  • Fix E203 to accept NumPy slice notation a[0, :]. (Issue #13)

  • Performance improvements.

  • Fix decoding and checking non-UTF8 files in Python 3.

  • Fix E225: reject True+False when running on Python 3.

  • Fix an exception when the line starts with an operator.

  • Allow a new line before closing ), } or ]. (Issue #5)

0.5.0 (2010-02-17)

  • Changed the —count switch to print to sys.stderr and set
    exit code to 1 if any error or warning is found.

  • E241 and E242 are removed from the standard checks. If you want to
    include these checks, use switch —select=E,W. (Issue #4)

  • Blank line is not mandatory before the first class method or nested
    function definition, even if there’s a docstring. (Issue #1)

  • Add the switch —version.

  • Fix decoding errors with Python 3. (Issue #13 [1])

  • Add —select option which is mirror of —ignore.

  • Add checks E261 and E262 for spaces before inline comments.

  • New check W604 warns about deprecated usage of backticks.

  • New check W603 warns about the deprecated operator <>.

  • Performance improvement, due to rewriting of E225.

  • E225 now accepts:

    • no whitespace after unary operator or similar. (Issue #9 [1])

    • lambda function with argument unpacking or keyword defaults.

  • Reserve “2 blank lines” for module-level logical blocks. (E303)

  • Allow multi-line comments. (E302, issue #10 [1])

0.4.2 (2009-10-22)

  • Decorators on classes and class methods are OK now.

0.4 (2009-10-20)

  • Support for all versions of Python from 2.3 to 3.1.

  • New and greatly expanded self tests.

  • Added —count option to print the total number of errors and warnings.

  • Further improvements to the handling of comments and blank lines.
    (Issue #1 [1] and others changes.)

  • Check all py files in directory when passed a directory (Issue
    #2 [1]). This also prevents an exception when traversing directories
    with non *.py files.

  • E231 should allow commas to be followed by ). (Issue #3 [1])

  • Spaces are no longer required around the equals sign for keyword
    arguments or default parameter values.

0.3.1 (2009-09-14)

  • Fixes for comments: do not count them when checking for blank lines between
    items.

  • Added setup.py for pypi upload and easy_installability.

0.2 (2007-10-16)

  • Loads of fixes and improvements.

0.1 (2006-10-01)

  • First release.

i am developing a python library with couple of modules and files. I have read through the pep8 rules given in the below link

https://www.python.org/dev/peps/pep-0008/

Is there any package or software available which can check the python styles and structure .

for example , indendation with spaces or tabs , variable conventions etc.

I am looking for a module which can perform this task..

Soviut's user avatar

Soviut

86.6k47 gold badges186 silver badges254 bronze badges

asked Aug 8, 2016 at 3:39

srinath's user avatar

2

The term for this is «linting». A python module called Pylint is available.

It checks for coding standards and errors with full customizability. It can be run from the command line, as part of a continuous integration workflow, integrated into various IDEs.

answered Aug 8, 2016 at 3:45

Soviut's user avatar

SoviutSoviut

86.6k47 gold badges186 silver badges254 bronze badges

6

pep8 — Python style guide checker

pep8 is a tool to check your Python code against some of the style conventions
in PEP 8.

Mailing List

http://groups.google.com/group/pep8

Features

  • Plugin architecture: Adding new checks is easy.
  • Parseable output: Jump to error location in your editor.
  • Small: Just one Python file, requires only stdlib. You can use just the
    pep8.py file for this purpose
  • Easy_installable, of course!

Installation

Just an easy_install pep8 ought to do the trick.

Example usage and output

$ pep8 optparse.py
optparse.py:69:11: E401 multiple imports on one line
optparse.py:77:1: E302 expected 2 blank lines, found 1
optparse.py:88:5: E301 expected 1 blank line, found 0
optparse.py:222:34: W602 deprecated form of raising exception
optparse.py:347:31: E211 whitespace before '('
optparse.py:357:17: E201 whitespace after '{'
optparse.py:472:29: E221 multiple spaces before operator
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'

You can also make pep8.py show the source code for each error, and
even the relevant text from PEP 8:

$ pep8 --show-source --show-pep8 testsuite/E111.py
testsuite/E111.py:2:3: E111 indentation is not a multiple of four
  print x
  ^
    Use 4 spaces per indentation level.

    For really old code that you don't want to mess up, you can
    continue to use 8-space tabs.

Or you can display how often each error was found:

$ pep8 --statistics -qq --filename=*.py Python-2.5/Lib
232     E201 whitespace after '['
599     E202 whitespace before ')'
631     E203 whitespace before ','
842     E211 whitespace before '('
2531    E221 multiple spaces before operator
4473    E301 expected 1 blank line, found 0
4006    E302 expected 2 blank lines, found 1
165     E303 too many blank lines (4)
325     E401 multiple imports on one line
3615    E501 line too long (82 characters)
612     W601 .has_key() is deprecated, use 'in'
1188    W602 deprecated form of raising exception

Quick help is available on the command line:

$ pep8 -h
Usage: pep8.py [options] input ...

Options:
  -h, --help           show this help message and exit
  -v, --verbose        print status messages, or debug with -vv
  -q, --quiet          report only file names, or nothing with -qq
  --exclude=patterns   exclude files or directories which match these comma
                       separated patterns (default: .svn,CVS,.bzr,.hg,.git)
  --filename=patterns  when parsing directories, only check filenames matching
                       these comma separated patterns (default: *.py)
  --ignore=errors      skip errors and warnings (e.g. E4,W)
  --repeat             show all occurrences of the same error
  --show-source        show source code for each error
  --show-pep8          show text of PEP 8 for each error
  --statistics         count errors and warnings
  --count              count total number of errors and warnings
  --benchmark          measure processing speed
  --testsuite=dir      run regression tests from dir
  --doctest            run doctest on myself

Feedback

Your feedback is more than welcome. Write email to
johann@rocholl.net or post bugs and feature requests on github:

http://github.com/jcrocholl/pep8/issues

Source download

The source code is currently available on github. Fork away!

http://github.com/jcrocholl/pep8/

Запустите pep8 в бесплатном хостинг-провайдере OnWorks через Ubuntu Online, Fedora Online, онлайн-эмулятор Windows или онлайн-эмулятор MAC OS

Это команда pep8, которую можно запустить в бесплатном хостинг-провайдере OnWorks, используя одну из наших многочисленных бесплатных онлайн-рабочих станций, таких как Ubuntu Online, Fedora Online, онлайн-эмулятор Windows или онлайн-эмулятор MAC OS.

ПРОГРАММА:

ИМЯ

pep8 — инструмент для проверки вашего кода Python на соответствие некоторым стилевым соглашениям в PEP 8.

СИНТАКСИС

pep8 [

опционы

]

вход

ОПЦИИ

—версия
показать номер версии программы и выйти

-h, —Помогите
показать это справочное сообщение и выйти

-v, —подробный
распечатать сообщения о состоянии или выполнить отладку с помощью -вв

-q, —тихий
сообщать только имена файлов или ничего с -qq

—исключать=

описания

исключить файлы или каталоги, соответствующие этим шаблонам, разделенным запятыми (по умолчанию:
.svn, CVS, .bzr, .hg, .git, __ pycache__)

—имя файла=

описания

при разборе каталогов проверяйте только имена файлов, соответствующие этим разделенным запятыми
шаблоны (по умолчанию: * .py)

—Выбрать=

Ошибки

выберите ошибки и предупреждения (например, E, W6)

— игнорировать=

Ошибки

пропускать ошибки и предупреждения (например, E4, W)

—первый
показать первое появление каждой ошибки

-r, —повторить
(устарело) показать все вхождения одной и той же ошибки

—show-источник
показать исходный код для каждой ошибки

—show-pep8
показывать текст PEP 8 для каждой ошибки (подразумевает —first)

—статистика
подсчитывать ошибки и предупреждения

—считать
вывести общее количество ошибок и предупреждений как стандартную ошибку и установить код выхода равным 1
если сумма не равна нулю

—максимальная длина строки=

n

установить максимально допустимую длину строки (по умолчанию: 79)

— закрывающийся
повесить закрывающую скобку вместо совпадающего отступа строки открывающей скобки

—формат=

формат

установить формат ошибки [по умолчанию | pylint | ]

—diff сообщать только строки, измененные в соответствии с унифицированной разницей, полученной на STDIN

— тест
измерить скорость обработки

—config=

путь

расположение файла конфигурации пользователя (по умолчанию: $ HOME / .config / pep8)

ИСПОЛЬЗОВАНИЕ ПРИМЕРЫ

Отобразите, как часто обнаруживалась каждая ошибка:

% pep8 —statistics -qq пример / lib /

Показать исходный код и более подробное объяснение из PEP 8:

% pep8 —show-source —show-pep8 foo.py

Используйте pep8 онлайн с помощью сервисов onworks.net

Сообщество приняло набор стилевых рекомендаций PEP8, который Гвидо ван Россум, создатель языка, предложил еще в 2001 году. Как применять и когда отступать — рассказываем в этой статье.

Что такое стандарты PEP8 для языка Python

С предсказуемым кодом приятно работать: сразу понятно, где импортированные модули, константа здесь или переменная и в каком блоке текущая строка. Для предсказуемости важны стиль и оформление, особенно в Python, который многое прощает разработчику.

Требования PEP8 по оформлению Python-кода

Единообразие, наглядность и информативность — это основа PEP8. Страница с текстом предложения постоянно дополняется, рекомендуем иногда перечитывать.

Структура кода

В Python внутренние блоки кода выделяются отступами, а не специальными разделителями. Размер отступа — четыре пробела, табуляция не используется:

if (expression_is_true):
do_this()
elif (other_expression_is_true):
do_that()
else:
do_something_else()

Для удобства настройте табуляцию в любимом редакторе на проставление четырех пробелов.

Аргументы функций переносятся на следующую строку и выравниваются, если строка слишком длинная:

def long_func (arg_one, arg_two,
arg_three, arg_four)

def extra_long_function_name (
arg_one, arg_two, arg_three,
arg_four):
do_something()

Некоторые редакторы при переносе строки добавляют спецсимвол, поэтому вместо стандартных 80 символов максимальная длина строки в PEP8 — 79. Комментарии и документация — 72 символа.

Максимальную длину строки разрешается увеличить до 99 символов, если стандартные 79 ухудшают читаемость кода.

Знаки операций ставятся после переноса строки:

total_users = (currently_online
+ offline_but_active
+ offline_inactive
- duplicate_accounts
- banned)

Между функциями верхнего уровня и классами вставляются две пустые строки. Между определениями методов в классе — одна пустая строка. Разрешается добавлять пустые строки между логическими секциями, но не злоупотребляйте этим:

do_stuff()
do_similar_stuff()

do_different_stuff()

do_something_else_entirely()

Правила выбора имен

По правильно названной переменной или функции сразу понятно, зачем они нужны: в first_name лежит имя, а calculate_employee_salary() считает зарплату сотрудника.

Старайтесь использовать полные имена. Их проще читать, а с сокращениями вы и сами потом с трудом разберетесь:

# Правильно

first_name = ‘Ivan’
last_name = ‘Ivanov’

def plus_one (x):
return x + 1

# Неправильно

fnm = ‘Ivan’
lnm = ‘Ivanov’

# Plus 1? Phase 1? Point 1?
def p1 (x):
return x + 1

Придерживайтесь этих стилей именования:

Тип Рекомендация Примеры
Функция Одно или несколько слов в нижнем регистре, нижние подчеркивания для улучшения читаемости (snake case) function, add_one
Переменная Одна буква, слово или несколько слов в нижнем регистре, нижние подчеркивания для улучшения читаемости x, connection, first_name
Класс Одно или несколько слов с большой буквы без пробелов (camel case) Image, UserData
Метод Одно или несколько слов в нижнем регистре, нижние подчеркивания для улучшения читаемости draw(), get_user_data()
Константа Одна буква, слово или несколько слов в верхнем регистре, нижние подчеркивания для улучшения читаемости PI, MAX_CONNECTIONS
Модуль Короткое слово или слова в нижнем регистре, нижние подчеркивания для улучшения читаемости module.py, user_data.py
Пакет Короткое слово или слова в нижнем регистре без подчеркиваний package, userdata

Проверка истинности без знаков равенства

Условия с булевыми значениями проверяются без оператора эквивалентности (==):

# Правильно

if this_is_true:
do_something()

if not this_is_false:
do_something_else()

# Неправильно

if this_is_true == True:
do_something()

if this_is_false == False:
do_something_else()

Сравнение с None делается с помощью операторов is / is not:

if connection is None:
print_error_message()

if user is not None:
get_user_data()

Пустой массив, список, словарь или строка — это False. С содержимым — уже True:

first_name = ‘’

if not first_name:
do_something () # выполнится
colors = [‘red’]

if colors:
do_something_else() # выполнится

Использование комментариев

Хороший комментарий — полезный комментарий. Пользуйтесь простым и понятным языком и не забывайте обновлять их, если код меняется. Рекомендации PEP8:

  1. Пишите полные предложения с заглавной буквы, если это не название.
  2. Ставьте два пробела после точки в комментариях, кроме последнего предложения.
  3. Пишите на английском, если читатели не знают ваш язык.

Блочные комментарии объясняют следующий за ними участок кода. Выравнивайте их на том же уровне и начинайте каждую строку с # и пробела. Параграфы в блочных комментариях разделяются строкой с одной #:

# Returns a filled UserData object for the current user ID if user exists, None otherwise. Assumes database connection is already open
#
# TODO: very poor performance, rewrite it!

def get_user_data (db_connection, user_id)

Не злоупотребляйте комментариями на той же строке (внутренними). Они не должны объяснять очевидных вещей и затруднять чтение кода. Отделяйте их от текста как минимум двумя пробелами и начинайте с # и пробела:

# Правильно

first_name = ‘Ivan’ # test user, shouldn’t show up in prod

# Неправильно
first_name = ‘Ivan’ # first name

Пишите документацию для всех публичных модулей, функций, классов и методов. В приватных можно ограничиться комментариями, зачем они нужны и как используются.

В многострочных комментариях “”” в конце переносится на новую строку:

“””Run the provided database request. Scalar only!
For everything else, use db_query().
“””

В однострочных комментариях открывающие и закрывающие “”” — на той же строке:

“””Flush buffer and close the file”””

Выражения и инструкции

Стандартная кодировка для Python 3 — UTF8. В Python 2 — ASCII, которая не поддерживает кириллицу. Пользуйтесь Windows 1251 или аналогами:

# coding: cp1251
print (“Текст кириллицей”)

Импортируйте модули в начале файла, сразу после верхнеуровневых комментариев и строк документации. Группируйте их и разделяйте группы пустыми строками: сначала стандартная библиотека, потом — сторонние, в конце — локальные модули проекта. При импорте каждый модуль пишется с новой строки. Совмещайте несколько импортов из одного модуля:

import os
from math import pi, sin

Разделяйте условия, циклы и обработку исключений на отдельные строки, кроме тривиальных случаев:

# Правильно

if this_is_true
and that_is_true
and something_else_is_true:
do_stuff();
do_other_stuff();

# Допустимо
if file_position &amp;amp;lt; 0: file_position = 0 # file system quirk # Неправильно if this and that and something_else: do_stuff(); do_other_stuff() 

Использование запятых

Кортеж из одного элемента отделяется запятой и берется в скобки для улучшения читаемости. Для систем контроля версий элементы в списке пишутся с новой строки и отделяются запятыми, если список будет расширяться. В остальных случаях запятые не ставятся:

# Правильно

TEST_USERS = (‘ivanov_i’, )

TEST_ACCOUNT_IDS = [

‘123’,

‘456’,

]

# Неправильно

TEST_USERS = ‘ivanov_i’,

TEST_ACCOUNT_IDS = [‘123’, ‘456’, ]

Рекомендации по программированию

Определяйте функции с аннотациями типов аргументов и возвращаемых значений. Стрелка окружается пробелами с обеих сторон:

def sum(a: int, b: int) -&amp;gt; int:
return a + b

Для типов переменных вставляйте один пробел после двоеточия. Знак присваивания окружается пробелами с обеих сторон:

# Правильно

user_count: int

class UserData:
first_name: str = ‘replace_me’
login_and_password_hash: Tuple[str, str]

# Неправильно

user_count:int
user_count : int

class UserData:
first_name: str=’’

Не забудьте указать специальный комментарий, чтобы автоматические проверки игнорировали файл, если в проекте используются любые другие виды аннотаций:

# type: ignore

По умолчанию интерпретаторы Python должны игнорировать проверку типов и сохранять такое же поведение, как и без аннотаций. Линтеры и другой инструментарий — опциональны.

Другие рекомендации, на которые стоит обратить внимание:

  1. Используйте стандартную библиотеку, а не конкретную имплементацию (PyPy, CPython и т. д.).
  2. Реализуйте все операторы (__eq__, __ne__, __lt__, __le__, __gt__, __ge__) для сравнения элементов, не доверяйте внешнему коду в использовании только одного или нескольких.
  3. Определяйте функции ключевым словом def, а не знаком равенства: равенство оставляйте для лямбд.
  4. Наследуйте исключения от Exception вместо BaseException: BaseException зарезервировано для исключений, ловить которые — плохая идея.
  5. Сохраняйте стек вызовов при обработке цепочки исключений.
  6. Обрабатывайте конкретное исключение: слишком широкое условие (или пустой оператор except) поймает больше, чем нужно.
  7. Минимизируйте количество кода в try-блоке: в длинных условиях легче потеряться или проглотить ошибку.
  8. Очищайте локальные ресурсы с помощью with или try/finally.
  9. Вызывайте методы в менеджерах контекста явно. Исключение — резерв или возврат ресурса.
  10. Возвращайте единообразные значения: либо везде пустой return, либо везде результат или None.
  11. Проверяйте префиксы и суффиксы строк с помощью .startswith() и .endswith().
  12. Сравнивайте типы объектов через isinstance().
  13. Избегайте строковых литералов с пробельными символами в конце: некоторые редакторы и модули их обрежут.

Как проверить код на соответствие стандартам PEP8

Ручная проверка плохо подходит даже для небольших проектов: отнимает время, легко ошибиться. Используйте готовые инструменты:

  1. Среды разработки, например PyCharm.
  2. Pylint — для статического анализа и проверки стиля.
  3. Flake8 — для проверки стиля.

Pylint, Flake8 и многое другое лежит в разделе Python Code Quality Authority на гитхабе.

Когда можно проигнорировать соблюдение стандартов

Когда соблюдение стандартов ухудшает код. Помните: единообразный код понятнее и лучше читается. Например, PEP8 не применяется, если проект не доступен публично и уже использует другой стиль — или разрабатывался под старые версии Python. Для публичных библиотек PEP8 обязателен.

В проектах без единого стиля — договоритесь с командой и берите PEP8.

Коротко о главном

  1. Пишите единообразный код: его приятнее читать и легче воспринимать. PEP8 — стилевой стандарт сообщества.
  2. Выравнивайте блоки кода и отделяйте логические секции пустыми строками.
  3. Выбирайте понятные и однозначные имена для объектов.
  4. Добавляйте полезные комментарии. Обновляйте их, когда код меняется.
  5. Обрабатывайте исключения с узкими и краткими условиями.
  6. Берите автоматические инструменты проверки.
  7. Игнорируйте стандарты, если их соблюдение ухудшит код.

На чтение 34 мин Просмотров 5.1к. Опубликовано 22.02.2022

Python имеет чёткую внутреннюю систему принятия решений о направлениях дальнейшего развития, построенную на PEP — Python Enhancement Proposal. PEP -это документы, в которых, в строго определённой форме, выдвигаются предложения по улучшению языка и одновременно они являются полноценной документацией с обоснованием нововведения. Многие сходятся во мнении, что самым важным из них является PEP8. По крайней мере он является самым известным – тут сомневаться не приходится. Доступен сам PEP8 online на официальном сайте python. Так же можно найти PEP8 на русском. Именно о нём я расскажу в данном уроке.

Содержание

  1. О чём PEP 8
  2. Зачем нужен PEP 8
  3. Внешний вид кода
  4. Отступы
  5. Табуляция или пробелы?
  6. Максимальная длина строки
  7. Пустые строки
  8. Кодировка исходного файла
  9. Импорты
  10. Пробелы в выражениях и инструкциях
  11. Другие рекомендации
  12. Комментарии
  13. Блоки комментариев
  14. «Встрочные» комментарии
  15. Строки документации
  16. Соглашения по именованию
  17. Главный принцип
  18. Какие стили имён бывают
  19. Имена, которые не стоит использовать
  20. Имена модулей и пакетов
  21. Имена классов
  22. Имена исключений
  23. Имена функций
  24. Имена глобальных переменных
  25. Аргументы функций и методов
  26. Имена методов и переменных экземпляров классов
  27. Константы
  28. Проектирование наследования
  29. Общие рекомендации
  30. Избегайте волшебной палочки 
  31. Мы все ответственные пользователи 
  32. Автоматическая PEP8 проверка Python-кода
  33. Осознанная необходимость
  34. Когда лучше проигнорировать PEP8

О чём PEP 8

PEP8 — это свод рекомендаций по оформлению кода. Почему это важно? Дело в том, что оформление кода сильно влияет на читаемость, а каждый программист знает, что гораздо чаще читают, чем пишут.

PEP8 – является ключевым по тому, что создаёт общий для всех питонистов стандарт оформления кода Python, а значит, большинство программ будет написано так, как все привыкли и их будет легче читать. Что не менее важно, на PEP8 ориентируются всевозможные IDE, линтеры, pep8 checker -ы и т. д.

К созданию данного документа приложил руку непосредственно создатель языка – Гвидо ван Россум.

Сам PEP8 определяет иерархию важности единообразия оформления кода. Важнее всего сохранить единый стиль кода внутри функции, далее по важности идут модуль, затем проект и, в идеале, весь существующий код на Питоне.

Зачем нужен PEP 8

Представьте себе проект, на котором сменилось не одно поколение разработчиков. Приходит на этот проект новичок и ему надо разобраться в коде. Если каждый разработчик до этого придерживался своего стиля именования переменных, кто-то предпочитал использовать строки документации, а кто-то строчные комментарии и много, много импортов в разных местах, разобраться в таком коде довольно сложно. Лично я как-то искал причину простейшей ошибки, но потратил на это несколько часов из-за того, что другой разработчик нарушил предписание PEP8 о импортах.

Так же читаемость важна, когда Вы читаете свой собственный код, написанный ранее. Ни для кого не секрет, что программисты стремятся писать что-то новое только один раз, а потом переиспользовать уже написанное когда-то. Это сильно повышает продуктивность. Сможете ли Вы разобраться в своём коде, написанном год назад?

Именно для смягчения перечисленных затруднений и создан PEP8. В нём описан стандарт оформления кода, направленный на то, чтоб все «говорили на одном языке». Он вобрал в себя опыт матёрых разработчиков, которые знают, какой стиль оформления наиболее прост для восприятия.

Соблюдение PEP 8 на столько важно, что это первое, на что смотрят работодатели при поиске сотрудников. Если Ваш код не отличается чистотой и читаемостью, то, скорее всего, на его алгоритмическую составляющую даже не будут смотреть.

Внешний вид кода

Отступы

Строки, которые состоят из большего числа символов, чем рекомендуется (об этом позже), следует разбивать на несколько строк. Если в такой строке есть скобки (круглые, квадратные или фигурные), то части строки, которые переносятся, должны начинаться на уровне открывающей скобки. Так:


def telegram_sender(message):
    requests.get('{}{}/sendMessage?chat_id={}'
                 '&text={message}'.format(settings_local.URL,
                                          settings_local.TOKEN,
                                          settings_local.CHAT_ID,
                                          message=message))

Так же можно перечислять аргументы и с другими отступами, но тогда их не должно быть в строке с открывающей скобкой:


def telegram_sender(message):
    requests.get(
            '{}{}/sendMessage?chat_id={}'
            '&text={message}'.format(
                              settings_local.URL,
                              settings_local.TOKEN,
                              settings_local.CHAT_ID,
                              message=message))

Закрывающую скобку можно переносить на отдельную строку, но отступ должен сохраняться. Делать ли это, остаётся на усмотрение разработчика.


def telegram_sender(message):
    requests.get(
            '{}{}/sendMessage?chat_id={}'
            '&text={message}'.format(
                             settings_local.URL,
                             settings_local.TOKEN,
                             settings_local.CHAT_ID,
                             message=message
                             ))

Либо скобку можно оставлять в начале разбитой строки:


def telegram_sender(message):
    requests.get(
            '{}{}/sendMessage?chat_id={}'
            '&text={message}'.format(
                             settings_local.URL,
                             settings_local.TOKEN,
                             settings_local.CHAT_ID,
                             message=message
    ))

Делать ли это и каким способом, остаётся на усмотрение разработчика.

Если скобок нет или описанное выше разбиение невозможно, то начало переносимых строк не должно совпадать ни с одним уровнем вложенности:


RESHENIA_SELECTOR = 'body > main > section:nth-child(2) > ' 
                    'div > div > div.col.col' 
                    '--xs-12.col--md-8.col--lg-9 > ' 
                    'article > ul > p:nth-child(1) ' 
                    '> a > span > span:nth-child(2) > em'

Отступы у переносимых строк должны быть одинаковыми. Оборачивание в скобки разбиваемой строки предпочтительнее чем использовать обратную косую черту для переноса, как в последнем примере. Всё же в некоторых ситуациях применение обратной косой черты допустимо. Это касается языковых конструкций, в которых нельзя сделать по-другому. К примеру, конструкция with не может использовать неявные продолжения, как и assert:


assert 'очень длинная'
       'строка'
# Вывод:

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 2

    'строка'

IndentationError: unexpected indent

 

Process finished with exit code 1

Примеры неправильного оформления:


# Аргументы на первой линии запрещены, если не используется вертикальное выравнивание
def telegram_sender(message):
    requests.get('{}{}/sendMessage?chat_id={}'
            '&text={message}'.format(settings_local.URL,
                             settings_local.TOKEN,
                             settings_local.CHAT_ID,
                             message=message))

Совпадение отступов с первым уровнем вложенности
RESHENIA_SELECTOR = 'body > main > section:nth-child(2) > ' 
'div > div > div.col.col' 
'--xs-12.col--md-8.col--lg-9 > ' 
'article > ul > p:nth-child(1) ' 
'> a > span > span:nth-child(2) > em'

Табуляция или пробелы?

PEP8 рекомендует использовать не табуляцию, а четыре пробела на каждый уровень вложенности.

Использовать табуляции можно только если проект уже начат с таким стилем отступов. Смешивать табуляции и пробелы запрещено.

Максимальная длина строки

Строка кода не должна быть длиннее, чем 79 символов. Допустимо увеличение данного значения до 99 символов.

Для многострочных текстовых блоков, к примеру, таких как docstrings или комментарии, длина не должна превышать 72 символа.

Исторически данные ограничения возникли из-за экранов, имеющих ограничения по количеству символов в строке. Но и сейчас данное ограничение позволяет комфортно работать с несколькими окнами, а также системами контроля версий, когда проводится сравнение бок о бок, а так же с другими вспомогательными инструментами. Вообще, читать удобно «узкий код», скользя глазами сверху вниз.

Пустые строки

Монолитный код неудобен для восприятия. Точно так же, слишком много пустых строк в коде делает его очень разреженным, что вынуждает читающего пролистывать его чаще, чем необходимо.

Пустые строки (вертикальные пробелы) предназначены для визуального разделения логических частей кода. Так, стоит отделить объявление функций и классов двумя пустыми строками. Методы отделяются одной строкой.

Так же, вертикальные пробелы можно использовать для разбиения функций на группы. Если в коде идёт несколько однострочных блоков подряд, то их можно не разделять. Ещё можно использовать вертикальные отступы внутри функций и методов для выделения логических частей.

Если Вы правильно используете пустые строки, это может ощутимо повысить читаемость Вашего кода и помочь читающему определить, что этот код делает.

Кодировка исходного файла

Кодировка Python должна быть UTF-8.

Файлы в UTF-8 не должны иметь объявления кодировки.

Импорты

Рекомендуется располагать каждый импорт на отдельной строке

Правильно:


import string
import pathlib

Неправильно:

Однако, если из модуля импортируется несколько сущностей, то их следует перечислить в одной строке:


from pathlib import WindowsPath, PosixPath

Размещать импорты всегда следует в начале кода, сразу после строк документации. Сперва перечисляются импорты модулей из стандартной библиотеки, затем сторонние модули, а, в последнюю очередь, импорты самого проекта. Все три группы должны быть разделены вертикальным пробелом.

Между импортами и объявлением констант описывается спецификация __all__.

Абсолютное импортирование предпочтительнее относительного (помните, один из главных принципов Пайтон гласит: явное лучше, чем неявное).

Всё же относительный импорт допустим, если абсолютный является избыточным:

Никогда. НИКОГДА не делайте так:

Такая конструкция создаёт массу проблем. Подробнее об этом и об импортах вообще читайте в нашей статье Import Python 

Пробелы в выражениях и инструкциях

Не ставьте пробелы в следующих местах:

Между круглыми, квадратными или фигурными скобками и ближайшими к ним символами.

Правильно:


print('Привет землянам' + f' от {alien_species}')

Неправильно:


print( 'Привет землянам' + f' от {alien_species}' )

Перед запятой, точкой с запятой или двоеточием:

Правильно:

Неправильно:

Между именем функции, класса или метода и открывающей скобкой, после которой перечисляются аргументы:

Правильно:

Неправильно:

Перед скобкой, после которой указывается индекс, ключ или срез:

Правильно:

Неправильно:

Применение более, чем одного пробела перед оператором:

Правильно:


переменная_1 = 1
переменная_2 = 2
переменная_с_длинным_именем = 3

Неправильно:


переменная_1                = 1
переменная_2                = 2
переменная_с_длинным_именем = 3

Другие рекомендации

Перед бинарными операторами и после них всегда следует ставить. Вот их список:

присваивания (=, +=, -=, *=, /=, %=, //=), сравнения (==, <, >, !=, <>, <=, >=, in, not in, is, is not), логические (and, or, not).

Если символ = используется для установки параметру значения по умолчанию или передачи значения именованного аргумента, пробелы вокруг него не используются.


def foo(r, pi=3.14):
    return P(radius=r, pi=pi)

Неправильно:


def foo(r, pi = 3.14):
    return P(radius = r, pi = pi)

Не стоит вкладывать инструкции друг в друга.

Правильно:

Неправильно:

Здесь стоит оговориться, что так всё же можно писать в тех случаях, когда Вы пишите в консоли.

Нельзя писать в одну строку условные операторы и циклы если в они содержат более одной инструкции.

Комментарии

Комментарии довольно сложно поддерживать. Это означает что в реальном мире с дедлайнами и безответственными коллегами код меняют чаще чем комментарии к нему. Со временем это может привести к тому, что комментарий не соответствует коду и вводит в заблуждение. Существует мнение что хороший код не требует комментариев благодаря правильному именованию сущностей. Если Вы всё же взялись использовать комментарии, Вы обязаны исправлять комментарии всякий раз как меняете код.

Комментарий обязан быть законченной мыслью и начинаться с заглавной буквы, если только первое слово не имя сущности из кода, именованной со строчной буквы.

Точка в конце не ставится только если предложение короткое.

Комментарий должен оканчиваться двумя пробелами.

Комментарии должны быть написаны на английском языке.

Блоки комментариев

Блок комментариев обязан иметь тот же отступ, что и код, идущий после него. В начале каждой строки необходимо ставить символ «#» и пробел после него. Если в блоке есть разделение на абзацы, то они отделяются пустой строкой, но в её начале так же должен стоять символ «#».

«Встрочные» комментарии

Комментарии не стоит располагать в тех же строках, что и код. Если Вы всё же используете подобные конструкции, то должны отделить комментарий от кода хотя бы двумя пробелами, затем поставить знак «#» и снова один пробел, а уже после этого текст.

В комментариях нельзя писать очевидные вещи. Так же считается дурным тоном шутить – для этого есть тематические форумы, а код – это дело серьёзное. Плохой пример:


if a:  # Если а не ложно
    pass  # То ничего не делаем

Ещё один плохой пример:


print(str(map(lambda x: x ^ 2, [i / 3 for i in a])))  # Вот это я загнул)))

Строки документации

Строки документации должны быть во всех функциях, классах, модулях, пакетах. Необязательны они только в приватных методах.

В PEP 257 отдельно описывается хороший стиль написания docstrings. Закрывающие кавычки должны быть отделены от текста одним вертикальным пробелом.

Пример:


def foo():
    """
    Это функция - пример
    и она ничего не делает
    :return: None

    """
    pass

Но это правило не стоит применять к однострочным документациям.

Пример:


def foo():
    """ Это функция - пример """
    pass

Узнать о комментариях больше Вы можете в уроке комментарии в Python.

Соглашения по именованию

Именование – всегда непростой вопрос. И в Питоне это тоже так. Ниже будут приведены общие рекомендации.

Главный принцип

Имена сущностей, к которым имеет доступ пользователь должны говорить о предназначении сущности, а не о том, как она реализована.

Какие стили имён бывают

Вы можете встретить довольно много стилей именования сущностей. Привожу небольшую шпаргалку, чтоб Вам было проще сориентироваться как стиль вы видите.

Стили бывают следующих видов:

  • r — (строчная буква)
  • R — (заглавная буква)
  • lowercase — (слово в нижнем регистре)
  • lower_case_with_underscores — (слова из маленьких букв с нижними подчеркиваниями, «змеиный стиль»)
  • UPPERCASE — (заглавные буквы)
  • UPPERCASE_WITH_UNDERSCORES — (слова из заглавных букв с нижними подчеркиваниями)
  • CapitalizedWords — (слова с заглавными буквами, «верблюжий стиль»). Замечание: когда вы используете аббревиатуры в таком стиле, пишите все буквы аббревиатуры заглавными — HTTPServerError лучше, чем HttpServerError.
  • mixedCase — (отличается от верблюжьего стиля тем, что первое слово начинается с маленькой буквы, часто встречается в других языках программирования)
  • Capitalized_Words_With_Underscores — (слова с заглавными буквами и нижними подчеркиваниями)

st_mode – здесь st – префикс, означающий что поле имеет отношение к системным вызовам POSIX. Этот стиль называется «венгерская нотация» и в Python почти не используется.

В дополнение к перечисленным выше, существует несколько специфичных  форм записи имен с добавлением символа нижнего подчеркивания в начало или конец имени:

  • _var — слабый признак того, что это имя приватной сущности. Например, from module import * не будет импортировать сущности, чьи имена начинаются с одинарного символа нижнего подчеркивания.
  • var_ — применяют по соглашению для того чтобы предотвратить конфликт с зарезервированными словами Пайтона, например:

def foo(type_, raise_=None):
    pass

  • __var: — сильный признак того, что это имя приватной сущности. Он изменяет имя атрибута класса чтоб усложнить его нежелательное использование. Пример:

from pprint import pprint

class foo():
    __myattr = 'приватный'

pprint(dir(foo))
# Вывод:

['__class__',

'__delattr__',

'__dict__',

'__dir__',

'__doc__',

'__eq__',

'__format__',

'__ge__',

'__getattribute__',

'__gt__',

'__hash__',

'__init__',

'__init_subclass__',

'__le__',

'__lt__',

'__module__',

'__ne__',

'__new__',

'__reduce__',

'__reduce_ex__',

'__repr__',

'__setattr__',

'__sizeof__',

'__str__',

'__subclasshook__',

'__weakref__',

'_foo__myattr']

Здесь, как Вы видите, атрибут __myattr автоматически превратился в _foo__myattr.

  • __var__ — (двойное нижнее подчеркивание вокруг имени): магические или «дандер» методы или атрибуты, расположенные в пространствах имен, которыми может управлять пользователь. Например, __name__, __init__ или __call Подобный стиль использовать не стоит.

Имена, которые не стоит использовать

Избегайте использования в именах одиночных символов, которые похожи на цифры. Это l (строчная латинская буква «эль»), O (заглавная латинская буква «о») и I (заглавная латинская буква «ай»).

Имена модулей и пакетов

Из-за того, что некоторые операционные системы не восприимчивы к регистру и обрезают длинные названия файлов, модули и пакеты стоит называть как можно короче и имя должно быть записано в нижнем регистре. Если необходимо, в имени модуля можно использовать нижние подчёркивания, однако, в имени пакета это недопустимо.

Имена классов

Имена классов должны обычно соответствовать верблюжьему стилю.

Так же могут использоваться соглашения для именования функций (змеиный стиль), если интерфейс используется в основном как функции и задокументирован.

Имена исключений

Поскольку исключения – это тоже классы, к исключениям тоже применяется верблюжий стиль именования.

Имена функций

Имена функций должны быть составлены из буквенных символов в нижнем регистре, а слова разделяться знаками нижнего подчеркивания (змеиный стиль).

Имена глобальных переменных

Правила именования глобальных переменных такие же, как и при именовании функций – это должен быть змеиный стиль.

Есть нюанс, заслуживающий отдельного внимания. При импорте модуля при помощи конструкции from module import * импортируются все глобальные переменные. Как правило, это нежелательное поведение, поскольку такие переменные являются приватными по отношению к модулю. Чтобы этого избежать можно использовать описанный выше трюк с одиночным нижним подчёркиванием в начале имени, но такими переменными неприятно оперировать внутри модуля. Есть другой способ – дандер атрибут __all__. Если он указан в модуле, то при его импорте конструкцией from module import * будут импортированы только перечисленные в атрибуте __all__ сущности.

Аргументы функций и методов

Всегда стоит использовать self в качестве начального аргумента метода экземпляра объекта для передачи ссылки на объект.

Всегда стоит использовать cls в качестве начального аргумента метода класса для передачи ссылки на класс.

Если имя параметра конфликтует с зарезервированным ключевым словом Питона и Вы не можете подобрать синоним, следует добавить в конец имени одиночное нижнее подчеркивание, чем исказить написание имени или использовать аббревиатуру. В итоге, имя type_ лучше, чем имя tp.

Имена методов и переменных экземпляров классов

Для методов и переменных экземпляров классов действуют те же правила, что и для функций – используем змеиный стиль.

Если метод или параметр является приватным, следует добавить символ одиночного нижнего подчёркивания в начало имени.

Если класс предназначен для наследования, то, чтобы предотвратить конфликты с именами в классах-потомках, следует использовать двойные нижние подчёркивания в начале имён.

Как уже говорилось, Python искажает такие имена. По сути, это просто синтаксический сахар. Посмотрите на этот короткий пример:


class foo():
    _foo__myattr = 'приватный'
    __myattr = 'ещё_один_приватный'

print(foo._foo__myattr)
# Вывод:

ещё_один_приватный

Здесь мы получили в выводе «ещё_один_приватный» по тому, что __myattr и _foo__myattr – это одно и то же и мы просто переопределили значение атрибута.

Константы

Константы записывают заглавными буквами. Если имя константы состоит из нескольких слов, они разделяются одиночными нижними подчёркиваниями. Перечисляются константы (и инициализируются – заполняются значениями) в начале скрипта, сразу после спецификации __all__.

Проектирование наследования

Проблема уровней доступа не возникает, пока Вы пишете код самостоятельно. Но, представьте себе код, над которым работает несколько команд одновременно. На основе того, что Вы написали, пишут код другие разработчики. Теперь, если Вы что-то измените в своём коде, это может вызвать проблемы на другом конце проекта. Значит придётся поддерживать обратную совместимость – то, что написано однажды, должно существовать и дальше. Результатом такого положения дел, скорее всего, будет обрастание проекта «легаси» кодом. Это такой код, который работает, но от него все хотели бы избавиться. Но никто не может, так как этот кирпичик лежит в самом основании.

Чтобы облегчить разрешение подобных ситуаций была придумана инкапсуляция и интерфейсы. Суть в том, что Вы определяете, какие именно атрибуты и методы предоставите другим разработчикам. Такие сущности называются публичными, а их совокупность – интерфейсом. В дальнейшем Вам придётся поддерживать обратную совместимость только для интерфейса. Те же методы и атрибуты, которые относятся к внутренней реализации, называются приватными и остаются доступными только для Вас или Вашей команды. Здесь Вы вольны вносить любые изменения. Этот принцип называется инкапсуляцией. Определение того, какие сущности будут приватными, а какие публичными очень важная часть проектирования и требует достаточной квалификации.

Если есть сомнения – смело делайте сущность приватной. Приватную сущность легко сделать публичной, а вот в обратную сторону это не работает: что стало публичным, стало им навсегда.

Некоторые классы изначально создаются специально чтобы от них наследовали другие классы-потомки, которые расширяют или изменяют поведение родительского класса. Как правило, их называют абстрактными классами. Когда Вы проектируете такой класс, решите и явно укажите, какие атрибуты являются публичными, какие принадлежат интерфейсам подклассов, а какие используются только абстрактным базовым классом.

Перейдём к рекомендациям:

  • Публичные атрибуты (входящие в интерфейс) не должны иметь в начале имени знака нижнего подчеркивания.
  • Если наименование публичного атрибута создаёт конфликт с зарезервированным ключевым словом Питона, добавьте последним символом имени один знак нижнего подчеркивания.
  • Публичные атрибуты должны быть простыми и называться понятными именами. И не пишите сложные геттеры и сеттеры. Их легко добавить потом, если потребуется, при помощи свойств (properties).
  • Если Вы планируете класс таким образом, чтобы от него наследовались другие классы, но не хотите, чтобы подклассы унаследовали некоторые атрибуты, добавьте в имена два символа нижнего подчеркивания в начало, и ни одного — в конец. Таким образом Вы сделаете их приватными.

Постарайтесь избегать побочных эффектов (сопутствующих действий, не зафиксированных в сигнатуре), связанным с функциональным поведением, однако, такие побочные эффекты, как кэширование или логгирование, являются допустимыми.

Избегайте использования операций, требующих длительных или требовательных к ресурсам вычислений, потому что из-за записи с помощью атрибутов создается впечатление, что доступ происходит быстро.

Общие рекомендации

  • Код должен быть универсальным и написан таким образом, чтобы не зависеть от конкретной реализации языка (PyPy, Brython, Jython, IronPython, Nuitka, Cython и пр.).
  • Сравнения с None, как и во многих других языках программирования, должны непременно быть выполнены с применением операторов is или is not, но не с использованием операторов сравнения. Так же, вместо if x, следует писать if x is not None так как в некоторых случаях приведения типов значение None может быть приведено к значению False.
  • При реализации методов сравнения, лучше всего реализовать все 6 операций сравнения (__eq__, __ne__, __lt__, __le__, __gt__, __ge__), чем рассчитывать на то, что другие разработчики будут применять только определённый вид сравнения.

Вы можете использовать декоратор total_ordering() из модуля functools стандартной библиотеки для реализации недостающих методов.

  • Всегда стоит использовать выражение def, а не передавать в переменную ссылку на лямбда-выражение.

Правильно:

Неправильно:

  • При создании пользовательских классов исключений их следует наследовать от класса Exception, а не от BaseException. Прямое наследование от BaseException зарезервировано для исключений, которые не следует перехватывать. К примеру, это SystemExit и KeyboardInterrupt.
  • Python 3, «raise SomeError from OtherError» следует использовать для указания явной подмены исключения без потери отладочной информации.
  • Когда код перехватывает исключения в блоках try — except, перехватывайте конкретные ошибки.

Правильно:


def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError as ex:
        raise ValueError('b must not be zero')
divide(10, 0)
# Вывод:

Traceback (most recent call last):

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 3, in divide

        return a / b

ZeroDivisionError: division by zero

 

During handling of the above exception, another exception occurred:

 

Traceback (most recent call last):

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 6, in <module>

divide(10, 0)

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 5, in divide

        raise ValueError('b must not be zero')

ValueError: b must not be zero

 

Process finished with exit code 1

Неправильно:


def divide(a, b):
    try:
        return a / b
    except Exception as ex:
        raise ValueError('b must not be zero')
divide(10, '1')
# Вывод:

Traceback (most recent call last):

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 3, in divide

        return a / b

TypeError: unsupported operand type(s) for /: 'int' and 'str'

 

During handling of the above exception, another exception occurred:

 

Traceback (most recent call last):

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 6, in <module>

divide(10, '1')

File "C:UsersDushenkoAppDataRoamingJetBrainsPyCharm2021.3scratchesscratch.py", line 5, in divide

        raise ValueError('b must not be zero')

ValueError: b must not be zero

 

Process finished with exit code 1

Существуют и исключения из этого правила:

  1. Если обработчик выводит полную информацию о возникшем исключении.
  2. Если нужно выполнить какие-то действия после перехвата исключения, а потом вызвать его же в целях обработки в другом месте кода. Однако, всё же правильнее применять конструкцию «try-finally».
  • Надо стремиться оборачивать в конструкцию try-except как можно меньше кода, чтобы проще было перехватывать исключения.

Подробнее об исключениях Вы можете узнать в нашем уроке Try Except в Python

  • Когда какой-либо ресурс является локальным на определённом участке кода, применяйте выражение withдля того, чтобы после выполнения всех необходимых операций он был надёжно и оперативно очищен.
  • Используйте строковые методы вместо модуля string — они всегда быстрее и имеют тот же API для unicode-строк.
  • Используйте строковые методы ».startswith() и ».endswith() вместо срезов строк для проверки суффиксов или префиксов.

Правильно:


if bar.startswith('foo'):

Неправильно:

  • Сравнение типов объектов нужно делать с помощью isinstance(), а не прямым сравнением типов:

Правильно:

Неправильно:

  • Не забывайте, что коллекции, если они не содержат элементов, приравниваются к false. Используйте это в условных операторах:

Правильно:


if not my_list: pass

if my_set: pass

Неправильно:


if len(my_list): pass

if len(my_set) >= 0: pass

  • Не применяйте строковые константы, которые содержат пробелы в конце — такие символы невидимы, а многие среды разработки и редакторы кода обрезают их.
  • Не сравнивайте булевы типы с True и False с помощью двойного символа равно:

Правильно:

Неправильно:


if some_var == True: pass

Вообще неправильно:


if some_var is True: pass

Избегайте волшебной палочки 

Python – очень мощный язык. Он предоставляет разработчику широчайшие возможности и это позволяет использовать различные трюки. Вот некоторые из них:

  • изменить способ создания объектов
  • изменить способ импорта модулей интерпретатором Python
  • встроить подпрограммы на C.

Но у этих возможностей есть и обратная сторона – «фичеризм» — это когда программист пишет код используя неоправданно сложные конструкции. Такой код может быть эффективным, но читаемость его весьма невысока.

Я наблюдал ситуацию, когда на проекте, в котором участвовали как юниор, так и сеньор разработчики. «Сеньоры» писали код на своём уровне, используя мета программирование, дата классы, каскадное наследование и прочее, хотя, на мой взгляд, всё можно было бы написать с использованием обычных функций и код от этого только выиграл бы. В итоге «юниоры» буксовали в тщетных попытках разобраться в коде.

Пожалуйста, не увлекайтесь фичами. У Пайтона есть определённая философия и её ядром является то, что это язык очень высокого уровня. Это одна из причин его популярности. Язык высокого уровня – что это означает? Это означает, что не надо опускаться к подробностям реализации чего-либо. Пишите декларативно – отдавайте простые и ясные команды. Чаще всего самый простой путь будет самым лучшим. Не гонитесь за скоростью и оптимизацией каждой строки кода – Python «не про это».

Без сомнения, профессиональный разработчик должен знать множество трюков и фич своего языка, ведь изредка бывают ситуации, когда без них не обойтись. Но применять их стоит как можно реже – не убивайте читаемость и даже если у Вас чёрный пояс по Питону, пожалейте тех, кто придёт после Вас.

К примеру, следующий код выводит самый часто встречающийся элемент списка. Он короткий и, возможно, элегантный. Но, попробуйте разобраться как он работает:


test = [1, 2, 5, 4, 2, 1, 3, 1, 4, 6, 4]
print(max(set(test), key = test.count))
# Вывод:

1

Мы все ответственные пользователи 

Как Вы уже увидели, Python допускает множество хитрых трюков, и некоторые из них позволяют выстрелить себе в ногу.

Хорошим примером этого будет то, что клиентский код может переопределять атрибуты и методы объекта, ведь в Питоне на самом деле нет полноценной инкапсуляции. И это следствие философии Python, которую зачастую сложно воспринять представителям языков с высокой степенью защиты, таких как C++ или Java. Заключается эта философия всего в одной фразе: «Мы все ответственные пользователи».

Это означает, что вся инкапсуляция (и многое другое) держится на соглашениях, принятых в сообществе питонистов. Инкапсулируя атрибут, разработчик лишь говорит коллегам: этот атрибут – приватный, его использовать не стоит, но не прячет его на самом деле. И да, даже атрибут с двумя нижними подчёркиваниями в начале имени, может использовать клиентский код, но, если он будет это делать, он будет это делать на свой страх и риск – в отношении этого атрибута никто ничего не гарантировал, и он может быть изменён «владельцем» в любое время (на то он и приватный). В такой ситуации любое неправильное поведение или проблемы, появившиеся при внесении изменений в код, являются ответственностью клиентского кода. Вас предупредили.

Придерживаться этого соглашения приветствуется: любой метод или свойство, которые не были предназначены для публичного использования (клиентским кодом), должны иметь в начале символ одиночного или двойного нижнего подчеркивания. Это гарантирует лучшее межевание обязанностей и более простое изменение существующего кода.

Автоматическая PEP8 проверка Python-кода

К счастью, у нас есть огромное подспорье в оформлении кода – утилиты автоматической проверки. Сейчас они встроены в любую среду разработки. К примеру, PyCharm проверяет оформление «на лету» и подсвечивает проблемы. Жмём Ctrl + Alt + O и IDE наводит порядок в импортах. Нажимаем Ctrl + Alt + L и PyCharm сам форматирует код. А если необходимо выполнить работу, а среды разработки нет под рукой? На GitHub представлен целый раздел Python Code Quality Authority, где располагаются инструменты для повышения качества кода, в том числе инструменты для проверки стиля оформления на соответствие PEP 8: flake8, pep8-naming, pycodestyle.

Вот небольшой список утилит для помощи в форматировании кода:

pep8 – рекурсивно просматривает все файлы в директориях на соответствие оформления кода стандарту pep8

autopep8 — как и pep8, данная утилита может самостоятельно выявлять ошибки, а также исправлять их

autoflake — утилита помогает удалить импорты и переменные, которые не используются

unify — позволяет автоматически приводить строки в соответствие стандарту PEP 8

docformatter — позволяет автоматически приводить строки документации в соответствие стандарту PEP 8

pyformat – всё перечисленное в одном флаконе

Осознанная необходимость

Не забывайте, что знать PEP 8 Вы, как разработчик, должны, а следовать ему — не обязаны. Вы вынуждены соблюдать правила, касающиеся отступов, так как в противном случае интерпретатор скажет Вам: IndentationError: unexpected indent. Но в самом PEP 8 перечислены случаи, когда программист по своему усмотрению может и должен не выполнять рекомендации.

Чёткие ограничения действуют только для публичных проектов-библиотек.

Когда лучше проигнорировать PEP8

Чаще всего применять PEP8 очень даже стоит. Если вы безукоризненно исполняете все рекомендации PEP8, можно с уверенностью гарантировать «чистоту», высокий уровень читаемости кода и профессионализм программиста. Это принесет пользу всем соприкасающимся с Вашим кодом, от коллег до конечного заказчика продукта. Но все же некоторые рекомендации PEP8 неприменимы в следующих случаях:

  1. Когда соблюдение PEP8 нарушит совместимость с существующим программным обеспечением;
  2. Когда код, сопутствующий тому, над чем вы работаете, несовместим с PEP8;
  3. Когда код нужно оставить совместимым с неактуальными версиями Python.

Главной же причиной, по которой не стоит применять PEP8 являются стандарты оформления кода, принятые на проекте, но отличные от рекомендуемых PEP8. Чаще всего это бывает из-за того, что основной стек предприятия располагается вокруг другого языка и всё подгоняется под его стандарты в целях достижения единообразия. Не беда! Лишь бы всем было удобно. Не забывайте, что PEP8 – это всего лишь рекомендации.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Проблемные вопросы определения природы проявления ошибки при реализации тактического действия
  • Проверить текст на количество ошибок