Знание этих 5 подводных камней Python может сэкономить вам часы усилий по отладке.
1. Конкатенация строк без «+»
Две строки неявно объединяются, если они записаны одна за другой, даже без использования оператора «+». Это может быть актуально, например, если у нас есть список строк и мы забыли одну запятую .
Обратите внимание на отсутствующую запятую в списке:
my_list = ["one", "two" "three", "four", "five"] >>> len(my_list) 4 >>> my_list ["one", "twothree", "four", "five"]
Вместо того, чтобы поднимать SyntaxError
, эти строки просто объединяются , и мы получаем неожиданные результаты!
Неявная конкатенация строк :
a = "hello" "world" >>> a helloworld
2. Условное выражение и множественные присваивания
В Python мы можем назначить несколько переменных в одной строке. Кроме того, мы можем использовать условное выражение вместо более длинного оператора if-else.
Если обе функции объединены, мы должны быть очень осторожны !
condition = False x, y = (0, 1) if condition else None, None >>> x, y (None, None)
Это то, что мы ожидали, но что произойдет, если условие истинно?
condition = True x, y = (0, 1) if condition else None, None >>> x, y ((0, 1), None)
Теперь мы получаем три значения, что происходит?
Объяснение: Мы пытались использовать круглые скобки для улучшения читабельности, но теперь мы перепутали порядок вычислений ! Теперь x будет (0, 1), если условие истинно, и None в противном случае. И y всегда None .
Исправление:
Либо используйте согласованные скобки для обоих случаев:
condition = True x, y = (0, 1) if condition else (None, None) >>> x, y (0, 1)
Или в этом случае я предпочитаю обычный оператор if-else , который менее подвержен ошибкам:
if condition:
x, y = 0, 1
else:
x, y = None, None
3. Создание кортежа с одним элементом
Давайте создадим кортежи с разным количеством элементов и проверим их. Как вы знаете, кортежи создаются с помощью круглых скобок ()
:
t = ('one', 'two') for i in t: print(i) # Output: one two
Это то, что мы ожидали для двух элементов.
Теперь создайте пустой кортеж:
Выхода нет, чего мы и ожидали.
Теперь создайте кортеж с одним элементом:
t = ("one") # This is a string, not a tuple!!!
for i in t:
print(i)
# Output:
o
n
e
Мы печатаем три предмета по одному символу в каждом! Что случилось?
Объяснение: Если мы создаем кортеж с одним элементом со скобками, используемый синтаксис создает не кортеж, а строковый объект!
Исправление:
Запятая в скобках ДОЛЖНА использоваться для создания кортежа с одним элементом:
t = ("one",) for i in t: print(i) # Output: one
Еще одна ловушка:
У кого-то может возникнуть идея использовать явный конструктор кортежей с помощью tuple()
функции. Это действительно создаст объект кортежа, но при передаче строки этой функции он создает кортеж с одним символом для каждого элемента:
t = tuple("one") # ('o', 'n', 'e')
4. assert
утверждение со скобками
Оператор assert в Python — это удобный способ вставить отладочные утверждения в программу:
Если условие истинно, ничего не происходит, но если условие ложно, возникает AssertionError (только в режиме отладки). Это можно использовать для обнаружения ошибок, когда мы всегда ожидаем, что определенное условие будет истинным.
Оператор assert может принимать необязательное сообщение об ошибке, разделенное запятой:
a = "python" b = "javascript" >>> assert(a == b, "Both languages are different") # No AssertionError is raised!!! But at least you get a warning: <stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?
Почему не возникает AssertionError, когда две переменные явно не равны?
Объяснение: Оператор assert НЕ должен использоваться со скобками ! В противном случае весь оператор оценивается как один кортеж с логическим значением и строкой, а непустой кортеж всегда равен True.
Синтаксис согласно официальной документации без скобок:
assert expression ["," errormsg]
Исправление:
a = "python"
b = "javascript"
>>> assert a == b, "Both languages are different"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Both languages are different
5. Методы обновления списков/словарей на месте
Это может быть очевидно, но иногда мы все же забываем об этом и получаем неожиданные значения None .
Некоторые методы для списков любят append()
и sort()
изменяют список на месте и возвращают None ! Поэтому, когда мы присваиваем результат этой операции исходной переменной, объект равен None :
my_list = [1, 3, 2]
my_list = my_list.append(4)
# or
my_list = my_list.sort()
>>> my_list
None
Исправление:
Просто примените эти методы, не переназначая их переменной:
my_list = [1, 3, 2]
my_list.append(4)
my_list.sort()
>>> my_list
[1, 2, 3, 4]
То же самое верно для словарей и update()
функции!