Знание этих 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() функции!


5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии