Сегодня я хотел поделиться быстрым Советы по спасению жизни Об общей ошибке разработчики Python все еще имеют тенденцию делать.
TL; доктор
Не используйте смежные аргументы по умолчанию в Python , если у вас не очень хорошая причина сделать это.
Почему? Потому что это может привести к тому, что всевозможные противные и ужасные ошибки дай тебе головные боли и тратить время каждого времени Отказ
Вместо этого по умолчанию для Нет
и назначьте смежное значение внутри функции.
Время историй
Эта ошибка поймала меня несколько раз в моем раннем путешествии разработчика.
- Когда я только что начал делать реальные проекты с Python (вероятно, 5-6 лет назад), я помню, как спотыкается с очень странной ошибкой. Список будет расти больше, чем ожидалось, когда функция была названа несколько раз, что бы странно вызвало ошибки.
- Оказавшись в колледже, нам присваивали проект по разработке алгоритма, и инструктор отправил нам программу, которая проверяла наш код. В какой-то момент я был абсолютно убежден, что мой код был правильным, но тесты продолжали провалиться.
В первом случае молодые разработчики-обучающиеся – как-отладопленные мне злились, потому что не понятия не имели, почему этот список становился слишком большим, и он провел Часы пытаясь исправить эту проблему.
Во втором случае другие сокурсники также столкнулись с проблемой, и не имел никакой подсказки, поэтому Время каждого было потрачено впустую Отказ
В обоих случаях время и усилия могли быть сохранены, если мы знали об этой распространенной ошибке.
Что мы делали не так?
Оказывается, в обоих случаях Пустой список использовался в качестве аргумента по умолчанию для функции Отказ Да, просто это. Что-то типа:
def compute_patterns(inputs=[]): inputs.append('some stuff') patterns = ['a list based on'] + inputs return patterns
Попробуйте себя: Если вы запустите эту функцию несколько раз, вы получите разные результаты!
>>> compute_patterns() ['a list based on', 'some stuff'] # Expected >>> compute_patterns() ['a list based on', 'some stuff', 'some stuff'] # Woops!
Хотя это не похоже на себя так много, входы = []
Был ли маленький мальчик, вызывающий этот беспорядок Отказ
Проблема
В Python при прохождении смежной ценности в качестве аргумента по умолчанию в функции Аргумент по умолчанию мутируется в любое время, когда значение мутируется .
Здесь «Mouseable Value» относится к чемумую, как список, словарь или даже экземпляр класса.
Что именно случилось?
Это не прямо вперед, чтобы увидеть, почему вышеизложенному факту может быть проблемой.
Вот что происходит подробно, используя другой пример:
def append(element, seq=[]): seq.append(element) return seq
>>> append(1) # seq is assigned to [] [1] # This returns a reference the *same* list as the default for `seq` >>> append(2) # => `seq` is now given [1] as a default! [1, 2] # WTFs and headaches start here…
Как видите, Python «сохраняет» значение по умолчанию и каким-либо образом связывает его на функцию. Поскольку он мутируется внутри функции, он также мутируется как по умолчанию. В конце концов, Мы используем другой по умолчанию каждый раз, когда функция называется – Дух!
Решение
Короче говоря, решение простое.
Использовать Никто как по умолчанию и назначьте мультипное значение внутри функции.
Так вместо этого делай это:
# 👇 def append(element, seq=None): if seq is None: # 👍 seq = [] seq.append(element) return seq
>>> append(1) # `seq` is assigned to [] [1] >>> append(2) # `seq` is assigned to [] again! [2] # Yay!
Это на самом деле очень распространенный узор в Python; Я нахожусь написать Если uver_var нет:
Буквально десятки времени в каждом проекте.
Настолько распространено, что есть предложение Python Sharceement (Pep), в настоящее время в работах ( PEP 505 – Необоснованные операторы ) Это, среди прочего, позволяют упростить вышеуказанный код и просто писать:
def append(element, seq=None): seq ??= [] # ✨ seq.append(element) return seq
Пеп по-прежнему – это черновик, но я просто хотел упомянуть это, потому что я действительно надеюсь, что не знаю операторы вскоре станут вещью в Python! 🔥
Уроки выучены
Там вы идете! Надеюсь, вы никогда не увидите себя, используя смежные значения по умолчанию в Python Code больше (за исключением того, что вы хотите связаться с нервами всех).
Если вы видите кого-то другого, используя их, распространяйте кончик и спасите свою жизнь тоже. 🙏
Оставайтесь на связи!
Если вам понравилось этот пост, вы можете Найди меня в Twitter Для обновлений, объявлений и новостей. 🐤
Оригинал: “https://dev.to/florimondmanca/python-mutable-defaults-are-the-source-of-all-evil-6kk”