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

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

Мы рассмотрим:

  • Неправильный отступ
  • ImportError, вызванная идентичными именами модулей
  • Изменяемые аргументы по умолчанию
  • Забыть двоеточие в конце структурных предложений
  • Несоответствие скобкам или скобкам
  • Неправильное применение функции инициализации
  • Изменение значений переменных класса без использования имени класса
  • Непонимание правил области видимости Python
  • Непонимание того, как Python связывает переменные в замыканиях
  • Утомительные итераторы
  • Подведение итогов и следующие шаги

1. Неправильный отступ

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

Чтобы исправить ошибку отступа, попробуйте:

  • Используйте пробелы или клавиши табуляции, но не комбинируйте их. Будьте внимательны, так как вы можете не осознавать, что объединили табуляции и пробелы, если полученный отступ выглядит одинаково. Вы можете попробовать использовать Python IDE или редактор кода, который предлагает инструмент поиска / замены для замены табуляции пробелами или наоборот.
  • Придерживайтесь количества пробелов, которые вы используете, если используете пробелы: вам не нужно использовать рекомендацию PEP 8 о четырех пробелах, но какое бы число вы ни выбрали, придерживайтесь его!

2. Ошибка ImportError, вызванная идентичными именами модулей

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

3. Использование изменяемых аргументов по умолчанию

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

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

def some_func(default_arg=[]):
    default_arg.append("some_string")
    return default_arg

print(some_func())
print(some_func())
print(some_func([]))
print(some_func())

=>['some_string']
=>['some_string', 'some_string']
=>['some_string']
=>['some_string', 'some_string', 'some_string']

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

def some_func(default_arg=None):
    if default_arg is None:
        default_arg = []
    default_arg.append("some_string")
    return default_arg

print(some_func())
print(some_func())
print(some_func([]))
print(some_func())
=>['some_string']
=>['some_string']
=>['some_string']
=>['some_string']

4. Забывание двоеточия в конце структурных приговоров

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

5. Несоответствие скобкам или скобкам.

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

6. Неправильное применение функции инициализации.

Используемая как конструктор, функция init создает объект или выделяет память для нового объекта класса. Функция init используется в качестве конструктора, когда объект создается из класса, и позволяет классу инициализировать атрибуты класса. Другими словами, он используется исключительно для установки значений. Однако распространенной ошибкой разработчиков Python является попытка использовать этот метод для возврата значений. Чтобы исправить это, просто поймите, что функция метода init в Python предназначена исключительно для использования в качестве конструктора.

7. Изменение значений переменных класса без использования имени класса

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

8. Непонимание правил области действия Python

Возможно, вы неправильно поняли правила области видимости Python, если ваш код возвращает «UnboundLocalError». Это распространенная ошибка, с которой сталкиваются разработчики Python при использовании списков.

Уникальный анализ области действия Python основан на правиле LEGB или локальном, охватывающем, глобальном, встроенном правиле. Следуя порядку правила LEGB, Python сначала предполагает, что любая переменная, назначенная в диапазоне, является локальной для этой области, и переопределит любую переменную с тем же именем в внешний вид. Это означает, что код, который работал должным образом при назначении переменной, может позже вернуть «UnboundLocalError», когда вы снова вызовете функцию.

В этом примере мы начинаем с кода, который работает должным образом.

x = 10
def bar():
    print(x)
bar()
=>10

Этот код возвращает «UnboundLocalError», когда мы назначаем переменную. Согласно порядку правила LEGB, Python распознает это новое присвоение значения «x» как локальную переменную, а не как переменную внешней области видимости.

x = 10
def foo():
    print(x)
    x += 1
foo()
=>Traceback (most recent call last):
=>  File "main.py", line 5, in <module>
=>    foo()
=>  File "main.py", line 3, in foo
=>    print(x)
=>UnboundLocalError: local variable 'x' referenced before assignment

Чтобы исправить «UnboundLocalError», вам просто нужно добавить оператор присваивания, чтобы явно объявить, что переменная является глобальной.

x = 10
def foobar():
    global x
    print(x)
    x += 1
foobar()
=>10

9. Непонимание того, как Python связывает переменные в замыканиях

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

Для получения дополнительной информации о замыканиях и переменных ознакомьтесь с этим кратким обзором замыканий и переменных Python.

10. Исчерпывающие итераторы

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

Этот тип ошибки может выглядеть так: вы можете вызвать функцию итератора в Python2, такую ​​как zip, для объединения двух списков и попытаться распечатать этот список позже. Теперь, если вы используете тот же код в Python3, он не вернет вам все значения сразу. Это потому, что вы исчерпали итератор, и у него нет оставшихся значений для возврата.

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

Посетите этот ресурс, чтобы узнать больше об итераторах в Python.

Подведение итогов и следующие шаги

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

Спасибо за чтение.

Удачного обучения!

Больше контента на plainenglish.io