Skip to content

Latest commit

 

History

History
313 lines (214 loc) · 13.6 KB

File metadata and controls

313 lines (214 loc) · 13.6 KB

Конспект PEP8

Введение

Код читается гораздо чаще, чем пишется.

Важно улучшать читаемость кода
и обеспечивать его единообразие.

Главное - быть последовательным.

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

4 пробела вместо табуляции

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

Строка кода 79 символов
(можно договориться в команде до 100).
Строка документации и комментариев 72 символа.

Перенос обратной косой чертой \ лучше избегать.
Перенос после логического оператора (and, or).

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

  1. Одна пустая строка - методы внутри класса,
    логические разделы внутри функции и группы импорта.
  2. Две пустые строки - классы и функции верхнего уровня.
  3. Дополнительные пустые строки - для различных групп похожих функций.

Кодировка в UTF-8.
Только английские слова.

Каждый импорт на отдельной строке, кроме from.
Порядок импортов:

  1. Из стандартной библиотеки.
  2. Из сторонней библиотеки.
  3. Из модулей текущего проекта.

Лучше абсолютный импорт, а не относительный (from .),
кроме случаев излишней подробности.

Нет шаблонам импортов (import *).

Контроль версий

Если вместо Git используется Subversion, CVS или RCS,
то для контроля версий:

"""Мой модуль. Делает полезные вещи."""

__version__ = "$Revision: 1a40d4eaa00b $"
# $Source$

import os
import sys

Строковые кавычки

Лучше выбрать двойные или одинарные кавычки
и использовать этот вариант в проекте.
Лишь иногда можно сделать исключение ради читаемости.

Тройные кавычки всегда двойные.

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

Нет пробелам внутри ()``{}``[]
Нет пробелам перед , ; :
Нет пробелам перед открывающейся скобкой,
при вызове функции, индексе, срезе.
Нет более одного пробелам вокруг оператора
(мол, для выравнивания с другими).

Нет пробелам вокруг операторов с высоким приоритетом
(для отделения от других операторов).

По пробелу всегда вокруг бинарного оператора:

  1. присваивания =, +=, -=, *= и т.д.
  2. сравнения ==, <, >, !=, <>, <=, >=, in, not in, is, is not
  3. логические and, or, not

По пробелу вокруг ->

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

Нет нескольким командам в одной строке.

Запятые в конце

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

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

Комментарии

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

Комментарий - законченное предложение.
Первое слово с большой буквы (кроме переменных).
Никогда не изменять регистр переменной.

Короткий комментарий - без точки в конце.

В блоке комментариев - после каждого точка.
Два пробела после точки,
кроме последнего предложения.

Комментарии всегда на английском.

У блока комментариев отступ такой же,
что и у кода, который он объясняет после него.

Абзац блока комментариев - одиночный #
и пробел после него

Избегать комментарии на той же строке.

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

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

Шаблон строки документации:

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""

Для однострочной документации закрывающиеся кавычки на той же строке.

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

Если в старой библиотеке правила нарушаются,
нужно писать в ее стиле.

Главный принцип - имена, видные,
как чаcть общественного API
должны отражать использование, а не реализацию.

_name - типо для внутренних нужд
(from M import * не будет импортировать).

class_ - для избежания конфликтов
с ключевыми словами python.

Атрибут класса Base.__name автоматически
переименовывается в Base._Base__name -
но она все равно доступна,
просто доступ затруднен.

__init__ - для магических методов.

Никогда не использовать однобуквенные
названия l, O, I (иногда неотличимы от 1, 0).

Должна быть совместимость с ASCII.

Модули - module, my_package.

Если модуль C/C++ дает Python какой-то модуль,
то такой должен начинаться с _ (_socket).

Классы - CapWords.

Причем соглашение о встроенных именах в Python:
1-2 слова слитно,
а CapWords для исключений и встроенных констант.

Типы переменных - CapWords,
лучше котороткие имена T, AnyStr, Num.

Исключения - классы => CapWords.
Можно написать Error в конце.

Нужно писать механизм __all__,
чтобы глобальные переменные не экспортировались.

Функции и глобальные переменные - my_name,
либо mixedCase, где уже такой стиль.

self - первый аргумент для метода экземпляра.
cls - первый аргумент для @classmethod.

Если возникают конфликты имен,
лучше class_ или синоним, чем clss.

Публичные методы и переменные экземпляров - my_name.
Непубличные - _name.
__name лучше только чтобы избежать конфликтов имен.

Константы - MAX_OVERFLOW.

Заранее решить, будет метод класса или экземпляр
публичным или непубличным.
Если есть сомнения - делать непубличным.

Публичные будут использовать другие,
а непубличные вы можете и удалить или изменить когда-нибудь.

Приватных атрибутов по сути в Python не бывает.

При проектировании базового класса для наследников
решить и указать, какие атрибуты публичные,
какие для API подклассов (защищенные)
и какие только для внутри базового класса (приватные).

Публичные атрибуты - понятные имена
без сложных методов доступа и изменения.

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

__name для базового класса, который
скрывает от своих наследников. Но тогда:

  1. У подкласса не должно быть такое же имя.
  2. Откладка и __getattr__() менее удобные.
  3. Не всем такое нравится, поэтому искать компромисс.

Гарантия обратной совместимости -
для публичных интерфейсов.

=> Чтобы можно было четко разделять
публичные и внутренние интерфейсы.

=> Модулям объявлять о публичном API
через __all__ атрибут.
__all__ = [], когда нет публичного API.

Пространство имен считается внутренним (приватным),
=> интерфейс внутри тоже внутренний.

Нет косвенному импорту,
кроме явно документированной части API модуля.

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

Коду не зависеть от разных реализаций языка
(PyPy, Jython, IronPython, Pyrex, Psyco) -
например, от эффективных операций у кого-то из.

Сравнения с None ТОЛЬКО через is None, is not None.

При реализации сравнения лучше реализовать сразу все 6:
__eq__, __ne__, __lt__, __le__, __gt__, __ge__.

Можно воспользоваться functools.total_ordering()
для недостающих методов.

Лучше def, чем lambda.

Наследовать лучше от Exception,так как от BaseException для тех, которые не надо перехватывать.

raise X from Y при явной замене,
проследить, чтобы без потери информации.

При генерации исключений лучше
новый синтаксис raise ValueError('message').

Перехватывать конкретные ошибки,
а не простой except.
В худшем случае except Exception:.
Исключение:

  1. Вывод пользователю всего
  2. Нужен некоторый код после перехвата, а потом вновь бросить для обработки в другом месте. Но лучше try...finally.

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

Минимум кода в try...except.

with для ресурса на локальном участке кода.

with с отдельной функцией,
если что-то кроме получение или освобождение ресурса.

Лучше строковые методы, чем модуль string.

Лучше .startswith() и .endswith(), чем срезы строк.

Лучше isinstance(), чем прямое сравнение типов.
Для проверки str и unicode
есть общий класс basestring.

[], () и "" - это False, так что лучше писать без len:
if not seq.

Опасны важные пробелы в конце строковых констант.

if cond: лучше, чем == True или is True.

Не использовать return, break, continue внутри finally,
так как при выходе за пределы набора finally отменяется исключение.