Рубрики
Без рубрики

Идиоматический Питон. Кодирование по-умному.

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

Автор оригинала: John Paul Seremba.

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

Джефф Кнупп в своей книге “Написание идиоматического Python” утверждает, что;

“”Мы можем подробно документировать ваш код, писать исчерпывающие модульные тесты и проводить обзоры кода три раза в день, но факт остается фактом: когда кому-то еще нужно внести изменения, код становится королем.”

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

Я перечислил 15 советов, которые помогут вам стать умным программистом на python.

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

if x <= y and y <= z:
  # do something

Хорошо

if x <= y <= z:
  # do something

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

name = 'John'; address = 'Kampala'
if name: print(name)
print(address)

Хорошо

name = 'John'
address = 'Kampala'
if name:
  print(name)
print(address)

3. Используйте Ложные и Правдивые концепции Одна вещь, которой следует избегать, – это прямое сравнение с Истинным, Ложным или Никаким. Термин “истинность” относится к ценностям, которые всегда будут считаться истинными, а “ложь” – к ценностям, которые всегда будут считаться ложными. Например, пустой список/последовательности [], пустые словари {} None, False, Ноль для числовых типов считаются “ложными”. С другой стороны, почти все остальное считается “правдивым”. Плохо

x = True
y = 0
if x == True:
  # do something
elif x == False:
  # do something else
if y == 0:
  # do something
ls = [2, 5]
if len(ls) > 0:
  # do something

Хорошо

(x, y) = (True, 0)
# x is truthy
if x:
  # do something
else:
  # do something else
# y is falsy
if not y:
  # do something
ls = [2, 5]
if ls:
  # do something

4. Замена тернарного оператора Python не имеет тернарного оператора (например: x ? True: False), что есть во многих языках. Однако может быть использована и альтернативная форма: Bad

a = True
value = 0
if a:
  value = 1
print(value)

Хорошо

a = True
value = 1 if a else 0
print(value)

5. Используйте ключевое слово ” in “ Многократная проверка переменной по ряду значений излишне многословна. Вместо этого используйте чек на существование. Плохо

city = 'Nairobi'
found = False
if city == 'Nairobi' or city == 'Kampala' or city == 'Lagos':
  found = True

Хорошо

city = 'Nairobi'
found = city in {'Nairobi', 'Kampala', 'Lagos'}

Ключевое слово in также полезно при итерации по iterable. Плохо

cities = ['Nairobi', 'Kampala', 'Lagos']
index = 0
while index < len(cities):
  print(cities[index])
  index += 1

Хорошо

cities = ['Nairobi', 'Kampala', 'Lagos']
for city in cities:
  print(city)

6. Используйте ‘return’ для оценки выражений, в дополнение к возвращаемым значениям Bad

def check_equal(x, y):
  result = False
  
  if x == Y:
    result = True
  return result

Хорошо

def check_equal(x, y):
  return x == y

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

x = 'foo'
y = 'foo'
z = 'foo'

Хорошо

x = y = z = 'foo'

8. Форматирование строк Наихудшим подходом к форматированию строк является использование оператора + для объединения смеси статических строк и переменных. Однако самый ясный и идиоматичный способ форматирования строк – это использование функции format. Он принимает строку формата и заменяет заполнители значениями. Плохо

def user_info(user):
  return 'Name: ' + user.name + ' Age: '+ user.age

Хорошо

def user_info(user):
  return 'Name: {user.name} Age: {user.age}'.format(user=user)

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

ls = list()
for element in range(10):
  if not(element % 2):
    ls.append(element)
# We may also employ a lambda function
ls = list(filter(lambda element: not(element % 2), range(10)))

Хорошо

ls = [element for element in range(10) if not(element % 2)]
10. enumerate(list)

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

ls = list(range(10))
index = 0
while index < len(ls):
  print(ls[index], index)
  index += 1

Хорошо

ls = list(range(10))
for index, value in enumerate(ls):
  print(value, index)

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

emails = {}
for user in users:
  if user.email:
    emails[user.name] = user.email

Хорошо

emails = {user.name: user.email for user in users if user.email}

12. Наборы Рычаги воздействия на мощные операции набора. Понимание основных математических операций над множествами является ключом к использованию их силы. Объединение: Множество элементов в A, B или обоих (записывается как A | B) Пересечение: Множество элементов как в A, так и В B (записывается как A & B) Различие: Множество элементов в A, но не в B (записывается как A — B) NB Порядок имеет значение для Различия. А — Б-ЭТО НЕ то же самое, что Б — А. Симметричная разность: Набор элементов либо в A, либо в B, но не в обоих A и B (записывается как A ^ B) Плохо

ls1 = [1, 2, 3, 4, 5]
ls2 = [4, 5, 6, 7, 8]
elements_in_both = []
for element in ls1:
  if element in ls2:
    elements_in_both.append(element)
print(elements_in_both)

Хорошо

ls1 = [1, 2, 3, 4, 5]
ls2 = [4, 5, 6, 7, 8]
elements_in_both = list( set(ls1) & set(ls2) )
print(elements_in_both)

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

elements = [1, 3, 5, 2, 3, 7, 9, 2, 7]
unique_elements = set()
for element in elements:
  unique_elements.add(element)
print(unique_elements)

Хорошо

elements = [1, 3, 5, 2, 3, 7, 9, 2, 7]
unique_elements = set(elements)
print(unique_elements)

14. Используйте параметр по умолчанию ‘dict.get’ для предоставления значений по умолчанию Много раз мы упускаем из виду определение параметра по умолчанию при использовании dict.get(). Однако для того, чтобы избежать неприятного исключения KeyError, его хорошей практикой является предоставление значения по умолчанию. Плохо

auth = None
if 'auth_token' in payload:
  auth = payload['auth_token']
else:
  auth = 'Unauthorized'

Хорошо

auth = payload.get('auth_token', 'Unauthorized')

15. Не повторяйтесь (DRY) Всегда старайтесь не повторять блоки кода при написании кода. Всякий раз, когда вы обнаруживаете, что повторяете что-то, подумайте о создании вспомогательных методов/функций или даже переменных. DRY-это сложная модель программирования; вот очень хорошая статья, чтобы вы начали. Плохо

if user:
  print('------------------------------')
  print(user)
  print('------------------------------')

В приведенном выше примере мы повторили — более 30 раз, что на самом деле не очень хорошо. Мы можем улучшить его таким образом: Хорошо

if user:
  print('{0}\n{1}\n{0}'.format('-'*30, user))

Есть еще много чего рассказать об идиоматическом python. Знания, которыми я поделился, – лишь верхушка айсберга. Подробные примеры и объяснения можно найти в книге Джеффа Кнуппа “Написание идиоматического Python”. Вы можете взять себе копию из здесь .