Python длина строки: Четыре способа найти длину строки в Python

Содержание

Четыре способа найти длину строки в Python

В некоторых случаях при работе со строками в Python нам необходимо определить длину строки. Сделать это можно несколькими способами, а какими — мы сейчас и узнаем.

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

Сделать это можно несколькими способами.

Определяем длину строки в Python: способ № 1

Начнём с общеизвестного и наиболее популярного — использования функции len(). Эта встроенная функция возвращает количество символов в исследуемой нами строке, определяя таким образом её длину. Тут всё элементарно, и вы можете проверить код ниже на любом онлайн-компиляторе:

# Находим длину строки в Python с помощью функции len()
str = 'otus'
print(len(str)) 

Итогом работы функции станет следующий вывод в терминал:

Ищем длину строки в «Питоне»: способ № 2

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

# Python-код возвращает длину строки
def findLen(str):
    counter = 0    
    for i in str:
        counter += 1
    return counter
str = "otus"
print(findLen(str))

Соответственно, наш вывод в консоли тоже будет равен 4.

Поиск длины строки в Python: способ № 3

Теперь давайте воспользуемся циклом while. Мы «нарежем» строку, укорачивая её на каждой итерации, в результате чего получим пустую строку и остановку цикла. А подсчёт количества итераций снова позволит нам вывести в терминал искомую длину.

# Python-код, возвращающий длину строки
def findLen(str):
    counter = 0
    while str[counter:]:
        counter += 1
    return counter

str = "otus"
print(findLen(str))

Находим длину строки в Python: способ № 4

Теперь воспользуемся строковым методом объединения.

Он принимает итеративный элемент, возвращая строку, являющуюся объединением строк в итерируемом нами элементе. Разделитель между элементами — исходная строка, для которой и вызывается метод. Применение метода объединения с последующим подсчётом объединённой строки в исходной строке тоже позволит нам получить длину строки на «Питоне».

# Python-код, возвращающий длину строки
def findLen(str):
    if not str:
        return 0
    else:
        some_random_str = 'py'
        return ((some_random_str).join(str)).count(some_random_str) + 1
str = "otus"
print(findLen(str))

Как и во всех примерах выше, в консоль выведется количество символов в строе ‘otus’, равное 4. Вот и всё!

Материал написан на основе статьи — «Find length of a string in python (4 ways)».

Хотите знать про Python гораздо больше? Записывайтесь на наш курс для продвинутых разработчиков:

Длина строки в списке строк python



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

for i in lst: 
    print(i.split('-'))


... output

['a', 'doa', 'a', 'h5t']
['a', 'rne']
['a', 'ece']
['a', 'ece']
['a', 'tnt', 'c', 'doa', 'd', 'nvc', 'a', 'nnm', 'a', 'h5t']
['a', 'tps']

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

len(i.split('-')) 

в этом случае вышеприведенное будет выглядеть следующим образом:

4
2
2
2
10
2

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

EDIT:

Результат должен выглядеть следующим образом:

['doa', 'h5t']
['rne']
['ece']
['ece']
['tnt', 'doa', 'nvc', 'nnm', 'h5t']
['tps']
python list
Поделиться Источник e9e9s     27 ноября 2017 в 15:52

3 ответа


  • Python имен в списке

    Так что я вроде как новичок в python и получил следующую проблему: Учитывая имена списков, найдите самый большой элемент в списке и замените его последним элементом. Например, список [Carlton, Quincy Adam, Bernard] станет [Carlton, Bernard, Adam, Quincy] . Предположим, что имена не пусты Я думал о…

  • python обрабатывать несколько строк одновременно

    У меня есть список строк, и я хочу удалить стоп-слова внутри каждой строки. Дело в том, что длина стоп-слов намного больше, чем строк, и я не хочу повторять сравнение каждой строки со списком стоп-слов. Есть ли способ в python, чтобы эти несколько строк одновременно? lis = [‘aka’, ‘this is a good…



3

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

Вложенное понимание списка сделает свое дело.

>>> l = ['a-bc-def-ghij-klm', 'abc-de' 'fg-hi']
>>> [[x for x in s.split('-') if len(x) == 3] for s in l]
[['def', 'klm'], ['abc']]

Поделиться timgeb     27 ноября 2017 в 15:57



2

Этот код:

lst = ['a-doa-a-h3t','a-rne','a-ece','a-ece','a-tnt-c-doa-d-nvc-a-nnm-a-h5t','a-tps']
for item in lst:
    words = item.split('-')
    print([word for word in words if len(word) == 3])

производит выход что-то вроде вашего требования:

['doa', 'h3t']
['rne']
['ece']
['ece']
['tnt', 'doa', 'nvc', 'nnm', 'h5t']
['tps']

Поделиться quamrana     27 ноября 2017 в 16:08



-1

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

for item in lst:
  for word in item.split('-'):
    if len(word) == 3:
      print(word)

Поделиться Chrispresso     27 ноября 2017 в 15:57


  • Разбейте строку Python на все возможные строки (длина-1)

    Представьте, что у меня есть строка s = ‘homeau’ и ее длина равна 6. Теперь я хочу разбить s на как можно больше строк, и длина каждой будет равна 5, пропуская один символ. После выполнения этой операции у меня будут все возможные строки типа: homea,homau,hoeau,omeau,hmeau,homau . Как я могу это…

  • В списке строк, как удалить строки, которые являются частью другой строки в списке?

    В списке строк, как удалить строки, которые являются частью другой строки в списке? Вот вам пример. lst = [‘Hello World’, ‘Hello’, ‘This is test’, ‘is test’] Я хотел бы получить только [‘Hello World’, ‘This is test’] в качестве вывода.


Похожие вопросы:


Как удалить строку из списка строк, если ее длина меньше длины строки с максимальной длиной в Python 2.7?

Как удалить строку из списка строк, если ее длина меньше длины строки с максимальной длиной в Python 2.7? В принципе, если у меня есть такой список, как: test = [‘cat’, ‘dog’, ‘house’, ‘a’, ‘range’,…


проверьте, находится ли строка в списке 2-GB строк в python

У меня есть большой файл ( A.txt ) из 2 GB, содержащий список строк [‘Question’,’Q1′,’Q2′,’Q3′,’Ans1′,’Format’,’links’,…] . Теперь у меня есть еще один файл большего размера (1 ТБ), содержащий…


совпадение строк в Python

У меня есть 300 тысяч строк, хранящихся в списке, и длина каждой строки составляет от 10 до 400. Я хочу удалить те, которые являются подстрокой других строк (строки с меньшей длиной имеют более…


Python имен в списке

Так что я вроде как новичок в python и получил следующую проблему: Учитывая имена списков, найдите самый большой элемент в списке и замените его последним элементом. Например, список [Carlton,…


python обрабатывать несколько строк одновременно

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

..


Разбейте строку Python на все возможные строки (длина-1)

Представьте, что у меня есть строка s = ‘homeau’ и ее длина равна 6. Теперь я хочу разбить s на как можно больше строк, и длина каждой будет равна 5, пропуская один символ. После выполнения этой…


В списке строк, как удалить строки, которые являются частью другой строки в списке?

В списке строк, как удалить строки, которые являются частью другой строки в списке? Вот вам пример. lst = [‘Hello World’, ‘Hello’, ‘This is test’, ‘is test’] Я хотел бы получить только [‘Hello…


Count количество списков в списке (вложенном списке) для каждой длины Python

У меня есть список списков, который содержит строки. Примерно следующий: [[‘apple’, ‘pear’, ‘apple’], [‘apple’, ‘apple’], [‘apple’, ‘pear’, ‘apple’,’apple’, ‘pear’, ‘apple’]] В этом списке…


длина каждого слова в списке (python) , а затем удаление этого слова, если это слово меньше некоторого числа(предположим, 5)

как я могу найти длину каждого слова в списке (python) , а затем удалить это конкретное слово, если длина этого слова меньше некоторого числа(предположим, 5): я новичок в python, так что,…


поиск строк в списке строк

У меня есть список python [‘100’, ‘20.0’, ‘?’, ‘a’, ‘0’] . Список содержит реальные ‘?’, ‘a’ строк и целых чисел и плавает кодировкой в строках. Я пытаюсь найти (реальные) строки ‘?’, ‘a’ в списке.

Какова максимальная длина строки python? Ru Python

С 64-разрядной установкой Python и, скажем, 64 ГБ памяти, строка Python 2 объемом около 63 ГБ должна быть вполне осуществимой (если не максимально быстрой). Если вы можете модернизировать свою память намного дальше (что будет стоить вам руки и ноги, конечно), ваши максимально возможные строки должны быть пропорционально дольше. (Я не рекомендую полагаться на виртуальную память, чтобы увеличить это на много, или ваше время выполнения будет просто смешно ;-).

Разумеется, с типичной 32-разрядной установкой Python общая память, которую вы можете использовать в своем приложении, ограничена чем-то вроде 2 или 3 ГБ (в зависимости от ОС и конфигурации), поэтому самые длинные строки, которые вы можете использовать, будут намного меньше в 64-битных установках со смехотворно большими объемами ОЗУ.

Я запустил этот код в экземпляре EC2.

def create1k(): s = "" for i in range(1024): s += '*' return s def create1m(): s = "" x = create1k() for i in range(1024): s += x return s def create1g(): s = "" x = create1m() for i in range(1024): s += x return s print("begin") s = "" x = create1g() for i in range(1024): s += x print(str(i) + "g ok") print(str(len(s)) + ' bytes') 

и это результат

 [ec2-user@ip-10-0-0-168 ~]$ time python hog.py begin 0g ok 1073741824 bytes 1g ok 2147483648 bytes 2g ok 3221225472 bytes 3g ok 4294967296 bytes 4g ok 5368709120 bytes 5g ok 6442450944 bytes 6g ok 7516192768 bytes 7g ok 8589934592 bytes 8g ok 9663676416 bytes 9g ok 10737418240 bytes 10g ok 11811160064 bytes 11g ok 12884901888 bytes 12g ok 13958643712 bytes 13g ok 15032385536 bytes 14g ok 16106127360 bytes 15g ok 17179869184 bytes 16g ok 18253611008 bytes 17g ok 19327352832 bytes 18g ok 20401094656 bytes 19g ok 21474836480 bytes 20g ok 22548578304 bytes 21g ok 23622320128 bytes 22g ok 24696061952 bytes 23g ok 25769803776 bytes 24g ok 26843545600 bytes 25g ok 27917287424 bytes 26g ok 28991029248 bytes 27g ok 30064771072 bytes 28g ok 31138512896 bytes 29g ok 32212254720 bytes 30g ok 33285996544 bytes 31g ok 34359738368 bytes 32g ok 35433480192 bytes 33g ok 36507222016 bytes 34g ok 37580963840 bytes 35g ok 38654705664 bytes 36g ok 39728447488 bytes 37g ok 40802189312 bytes 38g ok 41875931136 bytes 39g ok 42949672960 bytes 40g ok 44023414784 bytes 41g ok 45097156608 bytes 42g ok 46170898432 bytes 43g ok 47244640256 bytes 44g ok 48318382080 bytes 45g ok 49392123904 bytes 46g ok 50465865728 bytes 47g ok 51539607552 bytes 48g ok 52613349376 bytes 49g ok 53687091200 bytes 50g ok 54760833024 bytes 51g ok 55834574848 bytes 52g ok 56908316672 bytes 53g ok 57982058496 bytes 54g ok 59055800320 bytes 55g ok 60129542144 bytes 56g ok 61203283968 bytes 57g ok 62277025792 bytes 58g ok 63350767616 bytes 59g ok 64424509440 bytes 60g ok 65498251264 bytes 61g ok 66571993088 bytes 62g ok 67645734912 bytes 63g ok 68719476736 bytes 64g ok 69793218560 bytes 65g ok 70866960384 bytes 66g ok 71940702208 bytes 67g ok 73014444032 bytes 68g ok 74088185856 bytes 69g ok 75161927680 bytes 70g ok 76235669504 bytes 71g ok 77309411328 bytes 72g ok 78383153152 bytes 73g ok 79456894976 bytes 74g ok 80530636800 bytes 75g ok 81604378624 bytes 76g ok 82678120448 bytes 77g ok 83751862272 bytes 78g ok 84825604096 bytes 79g ok 85899345920 bytes 80g ok 86973087744 bytes 81g ok 88046829568 bytes 82g ok 89120571392 bytes 83g ok 90194313216 bytes 84g ok 91268055040 bytes 85g ok 92341796864 bytes 86g ok 93415538688 bytes 87g ok 94489280512 bytes 88g ok 95563022336 bytes 89g ok 96636764160 bytes 90g ok 97710505984 bytes 91g ok 98784247808 bytes 92g ok 99857989632 bytes 93g ok 100931731456 bytes 94g ok 102005473280 bytes 95g ok 103079215104 bytes 96g ok 104152956928 bytes 97g ok 105226698752 bytes 98g ok 106300440576 bytes 99g ok 107374182400 bytes 100g ok 108447924224 bytes 101g ok 109521666048 bytes 102g ok 110595407872 bytes 103g ok 111669149696 bytes 104g ok 112742891520 bytes 105g ok 113816633344 bytes 106g ok 114890375168 bytes 107g ok 115964116992 bytes 108g ok 117037858816 bytes 109g ok 118111600640 bytes 110g ok 119185342464 bytes 111g ok 120259084288 bytes 112g ok 121332826112 bytes 113g ok 122406567936 bytes 114g ok 123480309760 bytes 115g ok 124554051584 bytes 116g ok 125627793408 bytes Traceback (most recent call last): File "hog. py", line 25, in <module> s += x MemoryError real 1m10.509s user 0m16.184s sys 0m54.320s 

ошибка памяти после 116 ГБ.

 [ec2-user@ip-10-0-0-168 ~]$ python --version Python 2.7.12 [ec2-user@ip-10-0-0-168 ~]$ free -m total used free shared buffers cached Mem: 122953 430 122522 0 11 113 -/+ buffers/cache: 304 122648 Swap: 0 0 0 

Протестировано на EC2 r3.4xбольшой экземпляр с 64-разрядным Amazon Linux AMI 2016.09

Короткий ответ: если у вас более 100 ГБ ОЗУ, одна строка Python может использовать столько памяти.

36) длина строки Python — CoderLessons.com

len () — встроенная функция в python. Вы можете использовать len (), чтобы получить длину заданной строки, массива, списка, кортежа, словаря и т. Д.

Вы можете использовать функцию len для оптимизации производительности программы. Количество элементов, хранящихся в объекте, никогда не рассчитывается, поэтому len помогает указать количество элементов.

Синтаксис:

len(value)

Параметры:

Значение : заданное значение, длина которого вы хотите.

Возвращаемое значение

Он будет возвращать целочисленное значение, то есть длину данной строки, или массива, или списка, или коллекций.

Различные типы возвращаемых значений:

Строки:

Он возвращает количество символов в строке, которое включает знаки препинания, пробел и все типы специальных символов. Тем не менее, вы должны быть очень осторожны при использовании len переменной Null.

Слейте:

Пустой — это второй обратный вызов, который содержит ноль символов, но это всегда None.

Коллекции:

Встроенная функция len возвращает количество элементов в коллекции.

TypeError:

Функция Len зависит от типа передаваемой ей переменной. Non-Type не имеет встроенной поддержки.

Толковый словарь:

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

Пример 1: Как найти длину заданной строки?

# testing len() 
str1 = "Welcome to  Guru99 Python Tutorials"
print("The length of the string  is :", len(str1))

Вывод:

The length of the string  is : 35

Пример 2: Как найти длину списка в Python?

# to find the length of the list

list1 = ["Tim","Charlie","Tiffany","Robert"]

print("The length of the list is", len(list1))

Вывод:

The length of the list is 4

Пример 3: Как найти длину кортежа в Python

# to find the length of the tuple

Tup = ('Jan','feb','march')

print("The length of the tuple is", len(Tup))

Вывод:

The length of the tuple is 3

Пример 4: Как узнать длину словаря в Python?

# to find the length of the Dictionary

Dict = {'Tim': 18,'Charlie':12,'Tiffany':22,'Robert':25}

print("The length of the Dictionary is", len(Dict))

Вывод:

The length of the Dictionary is 4

Пример 5: Как найти длину массива в Python

# to find the length of the array

arr1 = ['Tim','Charlie','Tiffany','Robert']

print("The length of the Array is", len(arr1))

Вывод:

The length of the Array is 4

Резюме:

  • len () — это встроенная функция в python. Вы можете использовать len (), чтобы получить длину заданной строки, массива, списка, кортежа, словаря и т. д.
  • Значение: заданное значение, длина которого вы хотите.
  • Возвращаемое значение возвращает целочисленное значение, то есть длину заданной строки, или массива, или списка, или коллекций.

 

Длина строки считается неверно: unicode в python 2.7

Константы (string literals) "" создают байтовые строки в Питоне 2 (если from __future__ import unicode_literals не включено). Поэтому len("abc") возвращает количество байт.

u"" является строковой константой, которая всегда Unicode строки создаёт. len(u"abc") вернёт количество Юникодных символов (Unicode codepoint).

Некоторые буквы (user-perceived characters) могут состоять из нескольких символов. В этом случае, можно \X регулярное выражение использовать, чтобы найти количество «неразрывных/слитных» элементов текста (eXtended grapheme clusters):

>>> import regex # $ pip install regex
>>> text = u'я 😂 ё'         
>>> print(repr(text))
u'\u044f \U0001f602 \u0435\u0308'  # 6 code points
>>> regex.findall(ur'\X', text)    # 5 grapheme clusters
[u'\u044f', u' ', u'\U0001f602', u' ', u'\u0435\u0308'] 
>>> print " | ".join(regex.findall(ur'\X', text)) 
я |   | 😂 |   | ё  # 5 user-perceived characters

Дополнительно, существуют так называемые узкие сборки Питона 2, в которых не BMP-символы такие как 😂 представляются в виде utf-16 суррогатной пары (surrogate pair) — нарушение абстракции, что Юникодная строка является неизменяемой последовательностью Unicode сodepoint.

Вот ещё пример одного знака (emoji), который из нескольких юникод-cимволов состоит:

>>> emoji = u'\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466'
>>> print(emoji)
👩‍👩‍👧‍👦
>>> len(emoji)
7
>>> len(regex.findall(u'\X', emoji))
1

С точки зрения движения курсора, выделения, копирования, итд — этот эмодзи это один GUI элемент.

Для текстовых интерфейсов может иметь значение ширина напечатанной строки в терминале. python-prompt-toolkit использует wcwidth модуль:

>>> import wcwidth  # $ pip install wcwidth
>>> wcwidth.wcswidth(emoji)
8

Python: str() — работа со строками — Школа N61 г.Ульяновска

S = 'str';
S = "str";
S = '''str''';
S = """str"""
Литералы строк
S = "s\np\ta\nbbb" Экранированные последовательности
S = r"C:\temp\new" Неформатированные строки (подавляют экранирование)
S = b"byte" Строка байтов
S1 + S2 Конкатенация (сложение строк)
S1 * 3 Повторение строки
S[i] Обращение по индексу
S[i:j:step] Извлечение среза
len(S) Длина строки
S. find(str[, start[, end]) Поиск подстроки в строке. Возвращает номер первого вхождения (индекс подстроки в строке) или -1
S.rfind(str[, start[, end])Поиск подстроки в строке. Возвращает номер последнего вхождения или -1
S.index(str[, start[, end]) Поиск подстроки в строке. Возвращает номер первого вхождения или вызывает ValueError
S.rindex(str[, start[, end]) Поиск подстроки в строке. Возвращает номер последнего вхождения или вызывает ValueError
S.replace(old, new[, num]) Заменяет в строке S одну подстроку (old) на другую (new)
S.split([delimeter[, num]]) разбивает строку на подстроки в зависимости от разделителя
S.join(список) объединяет строки в одну строку, вставляя между ними определенный разделитель S
S.isdigit() возвращает True, если все символы строки — цифры
S.isnumeric() возвращает True, если строка представляет собой число
S.isalpha() возвращает True, если строка состоит только из алфавитных символов
S.isalnum() Состоит ли строка из цифр или букв
S.islower()возвращает True, если строка состоит только из символов в нижнем регистре. Знаки препинания и цифры дают True.
S.isupper()возвращает True, если все символы строки в верхнем регистре. Знаки препинания и цифры дают True.
S.isspace()Состоит ли строка из неотображаемых символов
(пробел,
символ перевода страницы (‘\f’),
«новая строка» (‘\n’),
«перевод каретки» (‘\r’),
«горизонтальная табуляция» (‘\t’) и
«вертикальная табуляция» (‘\v’))
S. istitle()Возвращает True, если ВСЕ слова в строке начинаются с заглавной буквы
S.startswith(str) Возвращает True, если строка начинается с подстроки str
S.endswith(str) Возвращает True, если строка заканчивается на подстроку str
S.capitalize() Переводит первый символ строки в верхний регистр, а все остальные в нижний
S.upper()переводит строку в вехний регистр
S.lower() переводит строку в нижний регистр
S.title() начальные символы всех слов в строке переводятся в верхний регистр
ord(символ) Символ в его код ASCII
chr(число)Код ASCII в символ
S.center(width, [fill]) если длина строки меньше параметра width, то слева и справа от строки равномерно добавляются пробелы, чтобы дополнить значение width, а сама строка выравнивается по центру
S.count(str, [start],[end]) Возвращает количество непересекающихся вхождений подстроки в диапазоне [начало, конец] (0 и длина строки по умолчанию)
S.expandtabs([tabsize]) Возвращает копию строки, в которой все символы табуляции заменяются одним или несколькими пробелами, в зависимости от текущего столбца. Если TabSize не указан, размер табуляции полагается равным 8 пробелам
S.lstrip([chars]) удаляет начальные пробелы из строки
S.rstrip([chars]) удаляет конечные пробелы из строки
S.strip([chars]) удаляет начальные и конечные пробелы из строки (удаление пробельных символов в начале и в конце строки). В параметре chars можно перечислить символы в любом порядке, которые следует удалить — удаляется символ, который присутствует в chars.
S.partition(шаблон) Возвращает кортеж, содержащий часть перед первым шаблоном, сам шаблон, и часть после шаблона. Если шаблон не найден, возвращается кортеж, содержащий саму строку, а затем две пустых строки
S.rpartition(sep) Возвращает кортеж, содержащий часть перед последним шаблоном, сам шаблон, и часть после шаблона. Если шаблон не найден, возвращается кортеж, содержащий две пустых строки, а затем саму строку
S.swapcase() Переводит символы нижнего регистра в верхний, а верхнего — в нижний
S.title() Первую букву каждого слова переводит в верхний регистр, а все остальные в нижний
S.zfill(width) Делает длину строки не меньшей width, по необходимости заполняя первые символы нулями
S.ljust(width, fillchar=" ") если длина строки меньше параметра width, то справа от строки добавляются пробелы, чтобы дополнить значение width, а сама строка выравнивается по левому краю
S.rjust(width, fillchar=" ") если длина строки меньше параметра width, то слева от строки добавляются пробелы, чтобы дополнить значение width, а сама строка выравнивается по правому краю
S.format(*args, **kwargs) Форматирование строки

Пограничные случаи — Python

Функция my_substr(), которую вы реализовали в прошлом уроке, содержит множество ошибок. «Но ведь она прошла проверки!». Да, но в этих проверках не было так называемых пограничных случаев. Функция нормально работала с нормальными аргументами, но как она поведёт себя, если передать ей такие варианты длины?

  • 0.
  • Отрицательное число.
  • Число, превышающее реальный размер строки.

Функция my_substr() не рассчитана на такие варианты. Можно подумать, что это не проблема: функция работает в нормальных условиях, и просто не нужно передавать ей «плохие» аргументы. В идеальном мире — да, но в реальном мире ваш код будет запускаться в разных ситуациях, с разными комбинациями условий и данных. Нельзя быть уверенным, что аргументы всегда будут корректными, поэтому нужно учитывать все случаи, в рамках здравого смысла.

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

Умение справляться с такими ошибками приходит с опытом, через постоянные косяки в стиле «ой, забыл проверить на пустую строку!».


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

string = 'If I look back I am lost'
print(my_substr(string, 0, 1))  # => 'I'
print(my_substr(string, 3, 6))  # => 'I look'

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

  • Отрицательная длина извлекаемой подстроки.
  • Отрицательный заданный индекс.
  • Заданный индекс выходит за границу всей строки.
  • Длина подстроки в сумме с заданным индексом выходит за границу всей строки.

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

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

Задание

Реализуйте функцию-предикат is_arguments_for_substr_correct(), которая принимает три аргумента:

  1. строку;
  2. индекс, с которого начинать извлечение;
  3. длину извлекаемой подстроки.

Функция возвращает False, если хотя бы одно из условий истинно:

  • Отрицательная длина извлекаемой подстроки.
  • Отрицательный заданный индекс.
  • Заданный индекс выходит за границу всей строки.
  • Длина подстроки в сумме с заданным индексом выходит за границу всей строки.

В ином случае функция возвращает True.

Не забывайте, что индексы начинаются с 0, поэтому индекс последнего элемента — это «длина строки минус 1».

Пример вызова:

string = 'Sansa Stark'
print(is_arguments_for_substr_correct(string, -1, 3))   # => False
print(is_arguments_for_substr_correct(string, 4, 100))  # => False
print(is_arguments_for_substr_correct(string, 10, 10))  # => False
print(is_arguments_for_substr_correct(string, 11, 1))   # => False
print(is_arguments_for_substr_correct(string, 3, 3))    # => True
print(is_arguments_for_substr_correct(string, 0, 5))    # => True

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics

Craft Your Python Like Poetry

Длина строки — это большое дело… программисты довольно много спорят по этому поводу. PEP 8, руководство по стилю Python, рекомендует максимальную длину строки 79 символов, но допускает, что длина строки до 100 символов приемлема для команд, которые соглашаются использовать определенную более длинную длину строки.

Итак, рекомендуется 79 символов … но разве длина строки не устарела? В конце концов, программисты больше не ограничены перфокартами, телетайпами и терминалами на 80 столбцов.На экране ноутбука, на котором я это печатаю, в каждой строке помещается около 200 символов.

Длина линии не устарела

Длина строки не является техническим ограничением: это ограничение, наложенное человеком. Многие программисты предпочитают короткие строки, потому что длинных строк трудно прочитать . Это верно как для типографики, так и для программирования.

Короткие строки легче читать.

В мире типографики для электронного текста рекомендуется длина строки 55 символов в строке (см. Длину строки в Википедии).Однако это не означает, что мы должны использовать ограничение в 55 символов; типографика и программирование разные.

Python — это не проза

Код

Python не структурирован, как проза. Английская проза состоит из плавных предложений: каждая строка переходит в следующую. В Python операторов чем-то похожи на предложений , что означает, что каждое предложение начинается с начала каждой строки.

Код

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

  Я стою посреди грохота Измученного прибоями берега, И держу в руке
Крупинки золотого песка - как мало! но как они ползают сквозь пальцы
глубина, Пока я плачу - пока плачу! О Боже! могу я не схватить их с
более тугая застежка? О Боже! не могу ли я спасти Одного от безжалостной волны? Это все, что мы
видеть или казаться Но мечта во сне?
  

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

  Я стою среди рев
Берега, измученного прибоями,
И я держу в руке
Зернышки золотого песка -
Как мало! но как они ползают
Сквозь пальцы в глубину,
Пока я плачу - пока плачу!
О Боже! я могу не понять
Их с более тугой застежкой?
О Боже! могу я не спасти
Один из безжалостных волн?
Все, что мы видим или кажемся
Но мечта во сне?
  

Примеры

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

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

Пример: завершение понимания

Длина этой строки кода превышает 79 символов:

 1
 
  employee_hours = [schedule.earliest_hour для сотрудника в self.public_employees для расписания в employee.schedules]
  

Здесь мы обернули эту строку кода так, чтобы она стала двумя более короткими строками:

 1
2
 
  employee_hours = [расписание.Early_hour для сотрудника в
                  self.public_employees для расписания в employee.schedules]
  

Мы можем вставить этот разрыв строки в эту строку, потому что у нас есть незакрытая квадратная скобка . Это называется неявным продолжением строки . Python знает, что мы продолжаем строку кода, когда есть разрыв строки внутри незакрытых квадратных скобок, фигурных или круглых скобок.

Этот код все еще не очень легко читать, потому что разрыв строки был вставлен произвольно.Мы просто обернули эту строку непосредственно перед строкой определенной длины. Здесь мы думали о длине строки, но совершенно не думали о удобочитаемости.

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

 1
2
3
 
  employee_hours = [schedule.earliest_hour
                  для сотрудника в self.public_employees
                  для расписания в employee.schedules]
  

У нас есть два разрыва строки, и мы специально вставили их перед нашим для предложений в этом понимании списка.

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

Вот еще один способ опровергнуть это утверждение:

 1
2
3
4
5
 
  employee_hours = [
    schedule.earliest_hour
    для сотрудника в self.public_employees
    для расписания в сотруднике.расписания
]
  

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

Пример: вызовы функций

Это поле модели Django, которому передается множество аргументов:

 1
2
3
 
  default_appointment = models.ForeignKey (othermodel = 'AppointmentType',
                                        null = True, on_delete = модели.SET_NULL,
                                        related_name = '+')
  

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

Вот то же поле модели Django с одним аргументом для каждой строки:

 1
2
3
4
 
  default_appointment = models.ForeignKey (othermodel = 'AppointmentType',
                                        null = True,
                                        on_delete = модели.SET_NULL,
                                        related_name = '+')
  

Мы разбиваем составные части (аргументы) этого оператора на отдельные строки.

Мы также могли бы обернуть эту строку, сделав отступ для каждого аргумента вместо их выравнивания:

 1
2
3
4
5
6
 
  default_appointment = models. ForeignKey (
    othermodel = 'Тип встречи',
    null = True,
    on_delete = models.SET_NULL,
    related_name = '+'
)
  

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

 1
2
3
4
5
6
 
  default_appointment = models.ForeignKey (
    othermodel = 'Тип встречи',
    null = True,
    on_delete = models.SET_NULL,
    related_name = '+',
)
  

Какой из этих способов лучше всего обернуть эту строку?

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

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

Пример: связанные вызовы функций

Вот длинный список связанных методов набора запросов Django:

 1
 
  books = Book.objects.filter (author__in = избранное_authors).select_related ('автор', 'издатель'). order_by ('название')
  

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

 1
2
3
4
5
 
  books = Book.objects.filter (
    author__in = избранное_authors
) .select_related (
    "автор", "издатель"
) .order_by ('название')
  

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

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

 1
2
3
4
 
  книги = Book.objects \
    .filter (автор__in = любимые_авторы) \
    .select_related ('автор', 'издатель') \
    .order_by ('название')
  

Это работает, но PEP8 не рекомендует этого.

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

 1
2
3
4
 
  книг = (Книга.объекты
    .filter (автор__in = любимые_авторы)
    .select_related ('автор', 'издатель')
    .order_by ('название'))
  

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

Хотя этот стиль отступа немного странный. Вместо этого мы могли бы выровнять наш код круглыми скобками:

 1
2
3
4
 
  книги = (Book.objects
         .filter (автор__in = любимые_авторы)
         .select_related ('автор', 'издатель')
         .order_by ('название'))
  

Хотя я, вероятно, предпочел бы выровнять точки в этом случае:

 1
2
3
4
 
  книги = (Book.objects
             .filter (автор__in = любимые_авторы)
             .select_related ('автор', 'издатель')
             .order_by ('название'))
  

Также работает стиль, полностью основанный на отступах (здесь мы также переместили объектов в отдельную строку):

 1
2
3
4
5
6
7
 
  книги = (
    Книга
    .объекты
    .filter (автор__in = любимые_авторы)
    .select_related ('автор', 'издатель')
    .order_by ('название')
)
  

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

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

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

Я часто определяю длинные словари и списки, определенные в коде Python.

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

 1
2
3
 
  МЕСЯЦЕВ = {'Январь': 1, 'Февраль': 2, 'Март': 3, 'Апрель': 4, 'Май': 5,
          «Июнь»: 6, «июль»: 7, «август»: 8, «сентябрь»: 9, «октябрь»: 10,
          «Ноябрь»: 11, «декабрь»: 12}
  

Вот тот же словарь с каждой парой «ключ-значение» в отдельной строке, выровненной с первой парой «ключ-значение»:

 1
2
3
4
5
6
7
8
9
10
11
12
 
  МЕСЯЦЕВ = {'Январь': 1,
          'Февраль': 2,
          'Март': 3,
          'Апрель': 4,
          '5 мая,
          'Июнь': 6,
          'Июль': 7,
          'Августа': 8,
          'Сентябрь': 9,
          'Октябрь': 10,
          'Ноябрь': 11,
          'Декабрь': 12}
  

И снова тот же словарь, с каждой парой ключ-значение с отступом, а не с выравниванием (с запятой в конце также в последней строке):

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
  МЕСЯЦЕВ = {
    '1 января,
    'Февраль': 2,
    'Март': 3,
    'Апрель': 4,
    '5 мая,
    'Июнь': 6,
    'Июль': 7,
    'Августа': 8,
    'Сентябрь': 9,
    'Октябрь': 10,
    'Ноябрь': 11,
    'Декабрь': 12,
}
  

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

Питон — это Поэзия

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

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

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

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

PEP 8 — Руководство по стилю для кода Python

В этом документе приведены соглашения о кодировании для кода Python, содержащего стандартная библиотека в основном дистрибутиве Python. Пожалуйста, посмотрите сопутствующий информационный PEP, описывающий руководящие принципы стиля для кода C в реализации Python на языке C.

Этот документ и PEP 257 (Docstring Conventions) были адаптированы из Оригинальное эссе Гвидо из руководства по стилю Python с некоторыми дополнениями из Руководство по стилю Барри.

Это руководство по стилю со временем развивается по мере того, как выявленные и прошлые соглашения становятся устаревшими из-за изменений в сам язык.

Многие проекты имеют свои собственные рекомендации по стилю кодирования. В случае каких-либо конфликты, такие руководства для конкретного проекта имеют приоритет для этого проекта.

Одна из ключевых идей Гвидо заключается в том, что код читается гораздо чаще, чем это написано. Приведенные здесь рекомендации предназначены для улучшения удобочитаемость кода и сделать его согласованным во всем спектр кода Python. Как сказано в PEP 20, «читаемость имеет значение».

Руководство по стилю — это последовательность. Соответствие этому руководству по стилю это важно.Последовательность в рамках проекта важнее. Согласованность в рамках одного модуля или функции является наиболее важным.

Однако знайте, когда нужно быть непоследовательным — иногда руководство по стилю рекомендации просто не применимы. Если сомневаетесь, делайте все возможное суждение. Посмотрите на другие примеры и решите, что выглядит лучше всего. А также не стесняйтесь спрашивать!

В частности: не нарушайте обратную совместимость только для соблюдения это PEP!

Некоторые другие веские причины игнорировать конкретное правило:

  1. При применении директивы код будет менее читабельным, даже для тех, кто привык читать код, следующий за этим PEP.
  2. Чтобы соответствовать окружающему коду, который также его нарушает (возможно, по историческим причинам) — хотя это тоже возможность убирать чужой беспорядок (в истинном стиле XP).
  3. Поскольку рассматриваемый код появился еще до введения руководство, и нет никаких других причин для изменения этого кода.
  4. Когда код должен оставаться совместимым со старыми версиями Python, который не поддерживает функцию, рекомендованную руководством по стилю.

Используйте 4 пробела на каждый уровень отступа.

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

# Верный:

# Выровнено по открывающему разделителю.
foo = long_function_name (var_one, var_two,
                         var_three, var_four)

# Добавьте 4 пробела (дополнительный уровень отступа), чтобы отличать аргументы от остальных.def long_function_name (
        var_one, var_two, var_three,
        var_four):
    печать (var_one)

# Висячие отступы должны добавлять уровень.
foo = длинное_имя_функции (
    var_one, var_two,
    var_three, var_four)
 
# Неправильный:

# Аргументы в первой строке запрещены, если не используется вертикальное выравнивание.
foo = long_function_name (var_one, var_two,
    var_three, var_four)

# Требуется дополнительный отступ, поскольку он не различим.
def long_function_name (
    var_one, var_two, var_three,
    var_four):
    печать (var_one)
 

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

Дополнительно:

# Висячие отступы * могут * иметь отступ, отличный от 4 пробелов.
foo = длинное_имя_функции (
  var_one, var_two,
  var_three, var_four)
 

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

# Без дополнительных отступов.
если (this_is_one_thing и
    that_is_another_thing):
    сделай что-нибудь()

# Добавьте комментарий, который выделит редакторы
# поддержка подсветки синтаксиса.если (this_is_one_thing и
    that_is_another_thing):
    # Поскольку оба условия верны, мы можем заморозить.
    сделай что-нибудь()

# Добавить дополнительный отступ в строку условного продолжения.
если (this_is_one_thing
        and that_is_another_thing):
    сделай что-нибудь()
 

(Также см. Обсуждение того, следует ли разбивать до или после двоичного операторов ниже.)

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

my_list = [
    1, 2, 3,
    4, 5, 6,
    ]
результат = some_function_that_takes_arguments (
    'а', 'б', 'в',
    'd', 'e', ​​'f',
    )
 

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

my_list = [
    1, 2, 3,
    4, 5, 6,
]
результат = some_function_that_takes_arguments (
    'а', 'б', 'в',
    'd', 'e', ​​'f',
)
 

Пробелы — предпочтительный метод отступа.

Вкладки

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

Python 3 запрещает смешивать использование табуляции и пробелов для отступов.

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

При вызове интерпретатора командной строки Python 2 с параметр -t выдает предупреждения о коде, который незаконно смешивает табуляции и пробелы. При использовании -tt эти предупреждения становятся ошибками.Эти варианты настоятельно рекомендуются!

Ограничьте все строки до 79 символов.

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

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

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

Некоторые команды решительно предпочитают более длинную строчку. Для кода поддерживается исключительно или преимущественно командой, которая может прийти к соглашению по этому поводу проблема, можно увеличить лимит длины строки до 99 символов, при условии, что комментарии и строки документации по-прежнему заключены в 72 символы.

Стандартная библиотека Python консервативна и требует ограничения строки до 79 символов (и строки документации / комментарии до 72).

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

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

с open ('/ path / to / some / file / you / want / to / read') как file_1, \
     open ('/ путь / к / некоторому / файлу / записывается / записывается', 'w') как файл_2:
    file_2.write (file_1.read ())
 

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

Другой такой случай — с утверждениями.

Убедитесь, что продолжение строки сделано соответствующим образом.

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

# Неправильный:
# оператор находится далеко от своих операндов
доход = (валовая_заработка +
          taxable_interest +
          (дивиденды - qual_dividends) -
          ira_deduction -
          student_loan_interest)
 

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

Следуя традициям математики, обычно дает больше читаемый код:

# Верный:
# легко сопоставлять операторы с операндами
доход = (валовая_заработка
          + taxable_interest
          + (дивиденды - qual_dividends)
          - ira_deduction
          - student_loan_interest)
 

В коде Python допускается разрыв до или после двоичного файла. оператор, если соглашение согласовано локально.Для новых предлагается стиль Кнута.

Окружить определения функций и классов верхнего уровня двумя пробелами. линий.

Определения методов внутри класса заключены в один пробел. линия.

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

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

Код в основном дистрибутиве Python всегда должен использовать UTF-8 (или ASCII в Python 2).

Файлы, использующие ASCII (в Python 2) или UTF-8 (в Python 3), не должны иметь объявление кодировки.

В стандартной библиотеке нестандартные кодировки следует использовать только для в целях тестирования или когда в комментарии или строке документации необходимо упоминать автора имя, содержащее символы, отличные от ASCII; в противном случае, используя \ x, \ u, \ U или \ N escape-символы — предпочтительный способ включения не-ASCII данные в строковых литералах.

Для Python 3.0 и более поздних версий для стандартная библиотека (см. PEP 3131): все идентификаторы в Python стандартная библиотека ДОЛЖНА использовать только идентификаторы ASCII и ДОЛЖНА использовать Английские слова везде, где это возможно (во многих случаях сокращения и используются не английские технические термины).Кроме того, строка литералы и комментарии также должны быть в формате ASCII. Единственные исключения: (a) тестовые примеры для тестирования функций, отличных от ASCII, и (б) имена авторов. Авторы, чьи имена не основаны на Латинский алфавит (latin-1, набор символов ISO / IEC 8859-1) ДОЛЖЕН обеспечивать транслитерация их имен в этом наборе символов.

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

  • Импорт обычно должен быть в отдельных строках:

    # Верный:
    импорт ОС
    import sys
     
    # Неправильный:
    import sys, os
     

    Можно сказать так:

    # Верный:
    из подпроцесса импорта Popen, PIPE
     
  • Импорт всегда помещается в начало файла, сразу после любого модуля комментарии и строки документации, а также перед глобальными переменными и константами модуля.

    Импорт следует сгруппировать в следующем порядке:

    1. Стандартная библиотека импорта.
    2. Связанный импорт третьих сторон.
    3. Импорт для локального приложения / библиотеки.

    Вы должны поместить пустую строку между каждой группой импорта.

  • Рекомендуется абсолютный импорт, так как он обычно более читабелен и, как правило, ведут себя лучше (или, по крайней мере, лучше ошибаются сообщения), если система импорта настроена неправильно (например, когда каталог внутри пакета попадает в sys.путь):

    import mypkg.sibling
    из mypkg import sibling
    из примера импорта mypkg.sibling
     

    Однако явный относительный импорт является приемлемой альтернативой абсолютный импорт, особенно при работе со сложными макетами пакетов где использование абсолютного импорта было бы излишне многословным:

    из . импортный брат
    из примера импорта .sibling
     

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

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

  • При импорте класса из модуля, содержащего класс, обычно хорошо написать это:

    из myclass import MyClass
    из foo.bar.yourclass импортировать YourClass
     

    Если это написание вызывает конфликты между местными именами, укажите их явно:

    импортировать мой класс
    импортировать foo.bar.yourclass
     

    и используйте myclass.MyClass и foo.bar.yourclass.YourClass.

  • Импорт подстановочных знаков (из import *) следует избегать, так как они делают неясным, какие имена присутствуют в пространстве имен, сбивает с толку как читателей, так и многие автоматизированные инструменты.Существует один оправданный вариант использования импорта с подстановочными знаками, который заключается в повторной публикации внутренний интерфейс как часть публичного API (например, перезапись чистая реализация интерфейса Python с определениями из дополнительного модуля ускорителя и какие именно определения будут перезаписаны заранее неизвестно).

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

Модуль уровня «dunders» (т.е. имена с двумя ведущими и двумя конечными подчеркивания), например __all__, __author__, __version__, и т. д. следует размещать после строки документации модуля, но до любого импорта выписки , кроме из импорта __future__. Python требует, чтобы future-import должен появиться в модуле перед любым другим кодом, кроме строки документации:

"" "Это пример модуля.

Этот модуль делает разные вещи.
"" "

from __future__ import barry_as_FLUFL

__all__ = ['a', 'b', 'c']
__version__ = '0,1'
__author__ = 'Кардинал Бигглс'

импорт ОС
import sys
 

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

# Верный:
ФАЙЛЫ = ('setup.cfg',)
 
# Неправильный:
FILES = 'setup.cfg',
 

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

# Верный:
ФАЙЛЫ = [
    'setup.cfg',
    'tox.ini',
    ]
инициализировать (ФАЙЛЫ,
           error = True,
           )
 
# Неправильный:
FILES = ['setup.cfg', 'tox.ini',]
инициализировать (ФАЙЛЫ, ошибка = Истина,)
 

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

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

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

Обычно различают следующие стили именования:

  • b (одна строчная буква)

  • B (одна заглавная буква)

  • строчная

  • lower_case_with_underscores

  • ВЕРХНИЙ

  • UPPER_CASE_WITH_UNDERSCORES

  • CapitalizedWords (или CapWords, или CamelCase — так названы потому, что ухабистого вида букв).Это тоже иногда известно как StudlyCaps.

    Примечание. При использовании аббревиатур в CapWords все буквы должны начинаться с заглавной буквы. буквы аббревиатуры. Таким образом, HTTPServerError лучше, чем HttpServerError.

  • смешанный регистр (отличается от CapitalizedWords начальным нижним регистром персонаж!)

  • Capitalized_Words_With_Underscores (уродливо!)

Есть также стиль использования короткого уникального префикса для группировки связанных имена вместе. Это не очень часто используется в Python, но упоминается для полноты.Например, функция os.stat () возвращает кортеж, элементы которого традиционно имеют такие имена, как st_mode, st_size, st_mtime и так далее. (Это сделано для того, чтобы подчеркнуть соответствие с полями структуры системного вызова POSIX, которая помогает программистам, знакомым с этим.)

Библиотека X11 использует начальный X для всех своих публичных функций. В Python, этот стиль обычно считается ненужным, потому что атрибут и имена методов имеют префикс объекта, а имена функций с префиксом имени модуля.

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

  • _single_leading_underscore: слабый индикатор «внутреннего использования». Например. from M import * не импортирует объекты, имена которых начинаются с подчеркиванием.

  • single_trailing_underscore_: используется по соглашению во избежание конфликтует с ключевым словом Python, например

    tkinter.Toplevel (мастер, класс _ = 'ClassName')
     
  • __double_leading_underscore: при именовании атрибута класса вызывает изменение имени (внутри класса FooBar __boo становится _FooBar__boo; см. ниже).

  • __double_leading_and_trailing_underscore__: «магические» объекты или атрибуты, которые живут в пространствах имен, контролируемых пользователем. Например. __init__, __import__ или __file__. Никогда не изобретайте такие имена; используйте их только так, как описано в документации.

Имена, которых следует избегать

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

В некоторых шрифтах эти символы неотличимы от цифры один и ноль.Когда возникает соблазн использовать «l», используйте вместо этого «L».

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

Модули

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

Когда модуль расширения, написанный на C или C ++, имеет сопутствующий Модуль Python, обеспечивающий более высокий уровень (например, более объектно-ориентированный) интерфейс, модуль C / C ++ имеет начальное подчеркивание (е.грамм. _разъем).

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

Имена классов обычно должны использовать соглашение CapWords.

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

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

Имена переменных типа

Имена переменных типа, представленные в PEP 484, обычно должны использовать CapWords. предпочитая короткие имена: T, AnyStr, Num.Рекомендуется добавить суффиксы _co или _contra к переменным, используемым для объявления ковариантных или контравариантное поведение соответственно:

от ввода import TypeVar

VT_co = TypeVar ('VT_co', ковариантный = Истина)
KT_contra = TypeVar ('KT_contra', контравариант = Истина)
 

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

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

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

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

Модули, предназначенные для использования через импорт из M *, должны использовать механизм __all__ для предотвращения экспорта глобальных объектов или используйте старое соглашение о префиксе таких глобальных переменных с подчеркиванием (которое вы можете указать, что эти глобальные объекты являются «модулем закрытый »).

Имена функций и переменных

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

Имена переменных следуют тому же соглашению, что и имена функций.

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

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

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

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

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

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

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

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

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

Python изменяет эти имена с помощью имени класса: если класс Foo имеет атрибут с именем __a, Foo не может получить к нему доступ.__a. (An настойчивый пользователь может получить доступ, вызвав Foo._Foo__a.) Как правило, двойное подчеркивание следует использовать только во избежание имя конфликтует с атрибутами в классах, предназначенных для создания подклассов.

Примечание: есть некоторые разногласия по поводу использования __names (см. Ниже).

Константы

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

Разработка для наследования

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

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

Мы не используем здесь термин «частный», поскольку на самом деле ни один атрибут private в Python (без ненужной работы).

Другая категория атрибутов — это те, которые являются частью «подкласс API» (часто называемый «защищенным» на других языках). Некоторый классы предназначены для наследования, расширения или изменения аспекты поведения класса. При проектировании такого класса возьмите заботиться о принятии четких решений о том, какие атрибуты являются общедоступными, которые являются частью API подкласса, и которые действительно только должны быть используется вашим базовым классом.

Имея это в виду, вот рекомендации Pythonic:

  • Открытые атрибуты не должны иметь начальных подчеркиваний.

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

    Примечание 1. См. Рекомендацию по именам аргументов выше для методов класса.

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

    Примечание 1. Свойства работают только с классами нового стиля.

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

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

  • Если ваш класс предназначен для создания подкласса, и у вас есть атрибуты что вы не хотите, чтобы подклассы использовали, рассмотрите возможность наименования их с двойные подчеркивания в начале и без подчеркивания в конце. Этот вызывает алгоритм изменения имени Python, где имя class искажается в имени атрибута. Это помогает избежать коллизии имен атрибутов должны непреднамеренно содержать подклассы атрибуты с тем же именем.

    Примечание 1. Обратите внимание, что в искаженном коде используется только простое имя класса. имя, поэтому, если подкласс выбирает одно и то же имя класса и атрибут name, вы все равно можете столкнуться с конфликтами имен.

    Примечание 2: изменение имени может использоваться в определенных целях, таких как отладка и __getattr __ (), менее удобно. Однако искажение имени алгоритм хорошо документирован и его легко выполнять вручную.

    Примечание 3: Не всем нравится искажать имена. Попытайтесь сбалансировать необходимо избегать случайного совпадения имен с потенциальным использованием продвинутые абоненты.

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

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

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

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

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

Импортированные имена всегда следует рассматривать как деталь реализации. Другие модули не должны полагаться на косвенный доступ к таким импортированным именам. если они не являются явно задокументированной частью содержащего модуля API, например os.path или модуль __init__ пакета, который предоставляет функциональность из подмодулей.

PEP 257 — Условные обозначения строк документации

Строка документации — это строковый литерал, который встречается как первая инструкция в определение модуля, функции, класса или метода.Такая строка документации становится специальным атрибутом __doc__ этого объекта.

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

Строковые литералы, встречающиеся в другом месте кода Python, также могут действовать как документация. Они не распознаются байт-кодом Python компилятор и недоступны в качестве атрибутов объекта среды выполнения (т.е. нет присвоено __doc__), но два типа дополнительных строк документов могут быть извлечено программными средствами:

  1. Строковые литералы, появляющиеся сразу после простого присваивания в вызывается верхний уровень модуля, класса или метода __init__ «строки документации атрибутов».
  2. Строковые литералы, появляющиеся сразу после другой строки документации, называется «дополнительные строки документации».

См. PEP 258, «Спецификация конструкции Docutils», для подробное описание атрибута и дополнительных строк документации.

Для единообразия всегда используйте «» «тройные двойные кавычки» «» вокруг строки документации. Используйте r «» «сырые тройные двойные кавычки» «», если вы используете какие-либо обратная косая черта в ваших строках документации. Для строк документации Unicode используйте u «» «Строки Unicode в тройных кавычках» «».

Есть две формы строк документации: однострочные и многострочные. строки документации.

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

def kos_root ():
    "" "Вернуть путь к корневому каталогу KOS."" "
    глобальный _kos_root
    если _kos_root: вернуть _kos_root
    ...
 

Примечания:

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

  • Котировки закрытия находятся на той же строке, что и котировки открытия. Этот выглядит лучше для однострочных.

  • Ни перед, ни после строки документации нет пустых строк.

  • Строка документации — это фраза, оканчивающаяся точкой.Он предписывает эффект функции или метода в виде команды («Сделай это», «Верни то»), не как описание; например не пишите «Возвращает путь …».

  • Однострочная строка документа НЕ должна быть «подписью», повторяющей параметры функции / метода (которые можно получить путем самоанализа). Не делать:

    Функция def (a, b):
        "" "функция (a, b) -> список" ""
     

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

    Функция def (a, b):
        "" "Сделайте X и верните список." ""
     

    (Конечно, «Do X» следует заменить полезным описанием!)

Многострочные строки документации состоят из итоговой строки, как однострочная docstring, за которой следует пустая строка, за которой следует более подробная описание.Сводная строка может использоваться при автоматическом индексировании. инструменты; важно, чтобы он умещался на одной линии и был отделен от остальную часть строки документации — пустой строкой. Строка сводки может быть на в той же строке, что и начальные котировки, или на следующей строке. Целиком docstring имеет такой же отступ, как и кавычки в первой строке (см. пример ниже).

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

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

Строка документации для модуля обычно должна перечислять классы, исключения и функции (и любые другие объекты), которые экспортируются модуль с однострочным описанием каждого из них. (Эти сводки обычно дают меньше деталей, чем итоговая строка в объекте docstring.) Строка документации для пакета (т. е. модуль __init__.py пакета) также должен содержать список модулей и подпакеты, экспортируемые пакетом.

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

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

Если класс является подклассом другого класса и его поведение в основном унаследованный от этого класса, в его строке документации следует упомянуть об этом и резюмируйте различия. Используйте глагол «переопределить», чтобы указать, что подкласса заменяет метод суперкласса и не вызывает метод суперкласса; используйте глагол «продлить», чтобы указать, что подкласс Метод вызывает метод суперкласса (в дополнение к своему собственному поведению).

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

комплекс def (real = 0,0, imag = 0,0):
    "" "Сформируйте комплексное число.

    Аргументы ключевого слова:
    real - реальная часть (по умолчанию 0.0)
    imag - мнимая часть (по умолчанию 0.0)
    "" "
    если imag == 0.0 и real == 0.0:
        вернуть complex_zero
    ...
 

Если вся строка документации не умещается в строке, поместите закрывающие кавычки. на линии сами по себе.Таким образом, команда Emacs fill-paragraph можно использовать на нем.

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

Поскольку код намного точнее слов, вот реализация алгоритма:

def trim (строка документации):
    если не строка документации:
        возвращаться ''
    # Преобразование табуляции в пробелы (следуя обычным правилам Python)
    # и разбить на список строк:
    lines = docstring.expandtabs (). splitlines ()
    # Определить минимальный отступ (первая строка не в счет):
    indent = sys.maxint
    для строки в строках [1:]:
        stripped = line.lstrip ()
        если лишить:
            indent = min (отступ, len (строка) - len (убрана))
    # Убрать отступы (первая строка особенная):
    trimmed = [строки [0].полоска()]
    если отступ 

Строка документации в этом примере содержит два символа новой строки и поэтому 3 строки. Первая и последняя строки пустые:

def foo ():
    "" "
    Это вторая строка документации."" "
 

Для иллюстрации:

>>> print repr (foo .__ doc__)
'\ n Это вторая строка строки документации. \ n'
>>> foo .__ doc __. splitlines ()
['', 'Это вторая строка строки документации.', '']
>>> обрезать (foo .__ doc__)
«Это вторая строка документации».
 

После обрезки эти строки документации эквивалентны:

def foo ():
    "" "Многострочный
    строка документации.
    "" "

def bar ():
    "" "
    Многострочный
    строка документации."" "
 

Руководство по стилю Python - участие в документации BigchainDB

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

Общие рекомендации по стилю программирования на Python

Наша отправная точка - PEP8, стандартное «Руководство по стилям для кода Python». Многие IDE Python будут проверять ваш код на соответствие PEP8. (Обратите внимание, что PEP8 не заморожен; он фактически меняется со временем, но медленно.)

BigchainDB использует Python 3.5+, поэтому вы можете игнорировать все рекомендации PEP8, относящиеся к Python 2.

Мы используем предварительную фиксацию, чтобы проверять некоторые из приведенных ниже правил перед каждой фиксацией, но еще не все реализовано. Используемые нами хуки можно найти в файле .pre-commit-config.yaml.

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

PEP8 говорит кое-что о строках документации, но не говорит о том, что в них вставлять или как их структурировать. PEP257 был одним из предложений для соглашений о строках документации, но вместо этого мы предпочитаем строки документации в стиле Google: их легче читать, а расширение napoleon для Sphinx позволяет нам превращать их в красивую документацию.Вот несколько ссылок на строки документации в стиле Google:

Максимальная длина линии

PEP8 имеет некоторые рекомендации по максимальной длине строки, начиная с «Ограничить все строки до 79 символов», но «для протекающих длинных блоков текста с меньшим количеством структурных ограничений (строки документации или комментарии) длина строки должна быть ограничена 72 символами. ”

Мы обсуждали это подробно, и похоже, что консенсус таков: попробуйте , чтобы длина строк была меньше 79/72 символа, если только у вас нет особой ситуации, когда более длинные строки улучшают читаемость.(Основная причина в том, что 79/72 работает для всех, а BigchainDB - это проект с открытым исходным кодом.) В качестве жесткого ограничения, все строки должны быть меньше 119 символов (что соответствует ширине обзора кода GitHub).

Одинарные или двойные кавычки?

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

 print ('Это не так уж красиво.')
print ("Разве это не выглядит лучше?")
 

Разрыв строк в нескольких строках

Следует ли использовать круглые скобки или косую черту ( \ ) для разделения строк на несколько строк, т.е.

 my_string = ('Это очень длинная строка, настолько длинная, что она не поместится только в одну строку'
             'поэтому он должен быть разделен на несколько строк.')
# или же
my_string = 'Это очень длинная строка, настолько длинная, что она не умещается только в одну строку' \
            'поэтому его нужно разбить на несколько строк.'
 

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

Как форматировать длинные операторы импорта

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

 из импорта Ткинтер (
    Tk, рамка, кнопка, запись, холст, текст,
    ВЛЕВО, ОТКЛЮЧЕНО, НОРМАЛЬНОЕ, КОНЕЦ, КОНЕЦ,
)

# Или же

из импорта Tkinter (Tk, Frame, Button, Entry, Canvas, Text,
                     ЛЕВЫЙ, ОТКЛЮЧЕННЫЙ, ОБЫЧНЫЙ, КОНЕЧНЫЙ)
 

Обоснование см. В PEP 328.

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

() для форматирования строк

Имеется выбор:

 x = 'имя:% s; оценка:% d '% (имя, n)
# или же
x = 'имя: {}; оценка: {} '. формат (имя, n)
 

мы используем формат () версия . В официальной документации Python говорится: «Этот метод форматирования строк является новым стандартом в Python 3, и его следует предпочесть форматированию%, описанному в разделе Операции форматирования строк в новом коде».

Написание и выполнение (Python) тестов

Содержимое этого раздела было перемещено в bigchaindb / tests / README.мкр .

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

Pep8 длина строки 80 очень странная: Python

Привет всем,

Я программирую уже около 15 лет и недавно получил работу в магазине, который настаивал на ограничении строки 80 символами. Это, кажется, расходится практически со всеми практиками программирования, которые я изучал со времен колледжа, потому что:

  1. описательных имен переменных значительно упрощают чтение и понимание кода

  2. описательных методов классов - просто отличная практика программирования

  3. пробелов в Python (оператор if в цикле for в методе класса теряет 12 символов

  4. Строковый формат выглядит очень странно, так как он в основном оказывается кучей пробелов слева и кучей текста на right

  5. логических строк, охватывающих несколько строк, читать намного сложнее

Для 1 и 2 я действительно читал, что люди хотели бы более короткие имена переменных и имена классов, при этом требуя строчные буквы и подчеркивания.Это кажется несовместимым друг с другом. Кроме того, честно говоря, «использовать более короткие имена» кажется невероятно глупой идеей точно так же, как использование x для всех ваших переменных - невероятно глупая идея.

3 здесь настоящий кикер. Каждое намерение занимает место и, учитывая правила форматирования, приводит к очень странно выглядящему коду. Например, если var1 в таком операторе, как .format (var1, начинается в столбце 55, следующая переменная начнется в столбце 55 на новой строке. Несколько переменных делают его похожим на блок кода, что очень странно видеть.Это почти раздражает, как будто этот блок кода имеет особое значение, поскольку он так ярко выражен в коде.

Для 5 я считаю это наиболее проблемным с SQL-запросами, но я легко вижу, что это беспорядок с argparse. На самом деле, я действительно не понимаю, как argparse может существовать в рамках этого стандарта. Кажется, просто не существует отличного способа передать короткое имя, длинное имя, количество аргументов, обязательное, значение по умолчанию, набор дополнительных аргументов, справочное сообщение и многое другое. без этого смотреть невозможно читать.

Кажется действительно странным, что эти правила пришли со времен c.В c я легко вижу, почему ограничение в 80 символов имеет смысл. Все представляет собой плоский файл, и 4 отступа, вероятно, означают, что в вашем коде произошло что-то плохое, и вам, вероятно, понадобится больше функций. Здесь 4 отступа - это условное выражение в цикле for для метода в классе. Я не знаю, есть ли какие-нибудь советы или уловки, чтобы обойти это? Стоит вообще заморачиваться? Похоже, что это огромный убийца производительности, поскольку я трачу гораздо больше времени на форматирование, чем на фактическое написание кода.

Чистый синтаксис кода для Python: Введение в руководство по стилю PEP 8 | Наука о данных о Земле