«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > ошибки ython, с которыми до сих пор сталкивается каждый разработчик, и способы их исправления)

ошибки ython, с которыми до сих пор сталкивается каждый разработчик, и способы их исправления)

Опубликовано 31 октября 2024 г.
Просматривать:662

ython bugs that every developer is still facing in and how to fix them)

Написано Рупешом Шармой, также известным как @hackyrupesh

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


1. Изменяемые аргументы по умолчанию: тихая ловушка

Проблема

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

Пример

def append_to_list(value, my_list=[]):
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Outputs: [1]
print(append_to_list(2))  # Outputs: [1, 2] - Unexpected!
print(append_to_list(3))  # Outputs: [1, 2, 3] - Even more unexpected!

Решение

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

def append_to_list(value, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Outputs: [1]
print(append_to_list(2))  # Outputs: [2]
print(append_to_list(3))  # Outputs: [3]

Ссылки

  • Попался аргумент Python по умолчанию

2. Неуловимая ошибка ключа в словарях

Проблема

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

Пример

data = {'name': 'Alice'}
print(data['age'])  # Raises KeyError: 'age'

Решение

Чтобы предотвратить ошибку KeyError, используйте метод get(), который возвращает None (или указанное значение по умолчанию), если ключ не найден.

print(data.get('age'))  # Outputs: None
print(data.get('age', 'Unknown'))  # Outputs: Unknown

Для вложенных словарей рассмотрите возможность использования defaultdict из модуля коллекций или библиотек, таких как dotmap или pydash.

from collections import defaultdict

nested_data = defaultdict(lambda: 'Unknown')
nested_data['name'] = 'Alice'
print(nested_data['age'])  # Outputs: Unknown

Ссылки

  • Ошибка Python KeyError и способы ее устранения

3. Незаметные ошибки при чрезмерном использовании try-кроме

Проблема

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

Пример

try:
    result = 1 / 0
except:
    pass  # Silently ignores the error
print("Continuing execution...")

В приведенном выше примере ошибка ZeroDivisionError перехватывается и игнорируется, но это может маскировать основную проблему.

Решение

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

try:
    result = 1 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
print("Continuing execution...")

Для более широкой обработки исключений вы можете использовать журналирование вместо pass:

import logging

try:
    result = 1 / 0
except Exception as e:
    logging.error(f"Unexpected error: {e}")

Ссылки

  • Попытки Python, кроме лучших практик

4. Целое деление: ловушка усечения

Проблема

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

Пример

print(5 / 2)  # Outputs: 2.5 in Python 3, but would be 2 in Python 2
print(5 // 2)  # Outputs: 2

Решение

Всегда используйте / для разделения, если только вам не требуется разделение по этажам. Будьте осторожны при переносе кода с Python 2 на Python 3.

print(5 / 2)  # Outputs: 2.5
print(5 // 2)  # Outputs: 2

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

from decimal import Decimal

print(Decimal('5') / Decimal('2'))  # Outputs: 2.5

Ссылки

  • Подразделение Python: / vs //

5. Утечки памяти из-за циклических ссылок

Проблема

Сборщик мусора Python выполняет большую часть управления памятью, но циклические ссылки могут вызвать утечки памяти, если они не обрабатываются правильно. Когда два или более объекта ссылаются друг на друга, они могут никогда не подвергаться сборке мусора, что приводит к увеличению использования памяти.

Пример

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = node2
node2.next = node1  # Circular reference

del node1
del node2  # Memory not freed due to circular reference

Решение

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

import weakref

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = weakref.ref(node2)
node2.next = weakref.ref(node1)  # No circular reference now

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

node1.next = None
node2.next = None
del node1
del node2  # Memory is freed

Ссылки

  • Управление памятью и сбор мусора в Python

Заключение

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


Написано Рупешом Шармой, также известным как @hackyrupesh

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/hackyrupesh/5-python-bugs-that-every-developer-is-still-facing-in-2024-and-how-to-fix-them-5f4p? 1. Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить их.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3