Python — один из наиболее элегантных и чистых языков программирования. Но красивый и чистый синтаксис не означает чистый код. И не избавляет разработчиков от необходимости изучать наилучшие приемы и шаблоны проектирования.
Процитируем Бьерна Страуструпа, создателя языка C++. Он дал очень четкое определение того, что можно считать чистым кодом.
«Я хочу, чтобы мой код был красивым и эффективным. Логика должна быть понятной — так багам будет сложнее спрятаться. Зависимостей должно быть как можно меньше — это облегчает поддержку. Обработка ошибок должна выполняться согласно определенной стратегии. А производительность должна быть приближена к оптимальной — чтобы не соблазнять людей заняться непринципиальными оптимизациями, которые могли бы запутать код. Чистый код делает что-то одно, и делает это хорошо».
Из этой цитаты мы можем выбрать несколько отличительных признаков чистого кода:
Конечно, разработчики вольны писать код так, как им нравится. Нет такого закона, который обязывал бы их писать исключительно чистый код. Но когда код написан плохо, это способствует накоплению технического долга и может повлечь за собой негативные последствия для компании. А это солидная причина писать код как можно лучше.
В этой статье мы рассмотрим несколько советов, как писать чистый код на Python.
Соглашения об именах — один из самых полезных и важных залогов написания чистого кода. Обдумывая, как назвать переменные, функции, классы и т. д., выбирайте осмысленные имена, раскрывающие ваши намерения. Это предполагает, что следует отдавать предпочтение длинным и описательным именам.
Несколько примеров:
Используйте длинные описательные имена, которые будет легко читать. Это избавит вас от необходимости писать лишние комментарии.
# Не рекомендуется # Переменная au - это число активных пользователей au = 105 # Рекомендуется total_active_users = 105
Имена должны раскрывать ваши намерения. Читая ваш код, другой разработчик должен по имени переменной понимать, что в ней хранится.
# Не рекомендуется
c = [“UK”, “USA”, “UAE”]
for x in c:
print(x)
# Рекомендуется
cities = [“UK”, “USA”, “UAE”]
for city in cities:
print(city)
Избегайте непонятных сокращений. Лучше пусть имя будет длинным, но понятным, чем коротким и при этом неоднозначным.
# Не рекомендуется fn = 'John' Ln = ‘Doe’ cre_tmstp = 1621535852 # Рекомендуется first_name = ‘JOhn’ Las_name = ‘Doe’ creation_timestamp = 1621535852
Используйте один и тот же набор слов. Непоследовательность будет путать читателя. Это касается не только имен переменных, файлов, функций, но даже и структуры директорий.
# Не рекомендуется
client_first_name = ‘John’
customer_last_name = ‘Doe;
# Рекомендуется
client_first_name = ‘John’
client_last_name = ‘Doe’
# Также обратите внимание на следующий пример:
# Не рекомендуется
def fetch_clients(response, variable):
# do something
pass
def fetch_posts(res, var):
# do something
pass
# Рекомендуется
def fetch_clients(response, variable):
# do something
pass
def fetch_posts(response, variable):
# do something
pass Начните отслеживать проблемы (issues) в кодовой базе в своем редакторе.
Для содержания кодовой базы в чистоте очень важно сделать так, чтобы другим разработчикам было легко видеть и отслеживать проблемы в коде. Когда вы можете это делать прямо в своем редакторе, вы:
Конечно, вы можете использовать различные инструменты для отслеживания технического долга, но лучше начать пользоваться соответствующими расширениями для редактора кода. Самые популярные из них также интегрируются с Jira, Linear, Asana и другими инструментами для управления проектами.
Не используйте магические числа. Это жестко прописанные числа, которые встречаются в коде без всяких объяснений. Обычно они появляются в виде литералов, причем неоднократно.
import random
# Не рекомендуется
def roll_dice():
return random.randint(0, 4) # what is 4 supposed to represent?
# Рекомендуется
DICE_SIDES = 4
def roll_dice():
return random.randint(0, DICE_SIDES)
При именовании функций строго придерживайтесь соглашения об именах. Использование разных подходов будет путать читателя.
# Не рекомендуется
def get_users():
# do something
Pass
def fetch_user(id):
# do something
Pass
def get_posts():
# do something
Pass
def fetch_post(id):
# do something
pass
# Рекомендуется
def fetch_users():
# do something
Pass
def fetch_user(id):
# do something
Pass
def fetch_posts():
# do something
Pass
def fetch_post(id):
# do something
pass Каждая функция должна выполнять какое-то одно действие и делать это хорошо. Пишите короткие и простые функции, выполняющие одну задачу. Полезный прием: если в имени вашей функции появляется союз «и», лучше разделить такую функцию на две разных.
# Не рекомендуется
def fetch_and_display_users():
users = [] # result from some api call
for user in users:
print(user)
# Рекомендуется
def fetch_usersl():
users = [] # result from some api call
return users
def display_users(users):
for user in users:
print(user) Не используйте Boolean flags. Это переменные, содержащие булевы значения — True или False. Они передаются в функцию для определения ее поведения.
text = "Python is a simple and elegant programming language."
# Не рекомендуется
def transform_text(text, uppercase):
if uppercase:
return text.upper()
else:
return text.lower()
uppercase_text = transform_text(text, True)
lowercase_text = transform_text(text, False)
# Рекомендуется
def transform_to_uppercase(text):
return text.upper()
def transform_to_lowercase(text):
return text.lower()
uppercase_text = transform_to_uppercase(text)
lowercase_text = transform_to_lowercase(text) Не добавляйте лишний контекст. Например, не следует добавлять ненужные слова к именам переменных.
# Не рекомендуется
class Person:
def __init__(self, person_username, person_email, person_phone, person_address):
self.person_username = person_username
self.person_email = person_email
self.person_phone = person_phone
self.person_address = person_address
# Рекомендуется
class Person:
def __init__(self, username, email, phone, address):
self.username = username
self.email = email
self.phone = phone
self.address = address В этом примере мы находимся внутри класса Person, поэтому нет нужды добавлять префикс person_ к каждой переменной класса.
Чтобы ваш код оставался организованным и поддерживаемым, распределяйте логику по разным файлам или классам — т. н. модулям. В Python модуль — это просто файл, имеющий расширение .py. Каждый модуль должен фокусироваться на какой-то одной задаче.
От редакции Pythonist. О модулях можно почитать в статье «Как импортировать в Python?».
Вы можете придерживаться принципов объектно-ориентированного программирования, таких как инкапсуляция, абстракция, наследование и полиморфизм.
Чистый код дает много преимуществ. Здесь и улучшение качества ПО, и легкая поддержка, и уменьшение технического долга.
В этой статье мы рассмотрели само понятие чистого кода и несколько советов о том, как писать чистый код на Python. Учтите, что это переходные знания: они вам пригодятся и при работе с любым другим языком программирования.
Перевод статьи «10 must-know patterns for writing clean code with Python».
Если вы ищете работу на Python, на Talanto.work сейчас есть варианты для junior, middle, senior…
Рынок Python-вакансий большой, но удобным его назвать сложно. Формально вакансий много, однако в реальном поиске…
Срезы в Python — это больше, чем a[2:7]. В статье — быстрый разбор полезных приёмов:…
В этой статье мы рассмотрим возведение в степень в Python с помощью различных методов, от…
Дубликаты в списке Python — частая проблема. В статье показано, как быстро убрать повторы, в…
Услуга виртуального хостинга на SpaceWeb позволяет арендовать часть сервера (shared-сервера) и разместить на нём свой…