Проблема: стандартный изменяемый объект
Но сначала разберёмся: что такое изменяемый объект в Python? Изменяемые объекты — это такие объекты, которые можно поменять. Список, множество и словарь — всё это изменяемые объекты.
Для примера опишем простенькую функцию:
def add(x, y=[]):
y.append(x)
return y
В данной функции add
зададим в список (то есть в изменяемый объект) переменную y
по умолчанию. Запускаем эту функцию:
def add(x, y=[]):
y.append(x)
return y
print(add('halil'))
print(add('yıldırım'))
Результатом выполнения будет:
['halil']
['halil', 'yıldırım']
Что здесь не так? Здесь идёт переписывание одного и того же списка. При первом вызове add('halil')
аргумент по умолчанию превратился в y=['halil']
и стал накладываться на тот же список. Давайте посмотрим, как это происходило:
def add(x, y=[]):
y.append(x)
return y
add('halil')
print(add.__defaults__)
add('yıldırım')
print(add.__defaults__)
Результат:
(['halil'],)
(['halil', 'yıldırım'],)
Получается так, что мы перезаписываем список, который был у нас по умолчанию.
Решение: изменяемый объект по умолчанию
В изменяемом объекте, вместо аргумента по умолчанию, используем None
. В нашем примере:
def add(x, y=None):
if y is None:
y = list()
y.append(x)
else:
y.append(x)
return y
print(add('halil'))
print(add('yıldırım'))
Результат:
['halil']
['yıldırım']
Проблема: копирование
Создадим словарь в Python.
a = {'a': 5, 'b': 4, 'c': 8}
Допустим, b
равно a
:
a = {'a': 5, 'b': 4, 'c': 8}
b = a
Удалим первый элемент с ключом a
.
del b['a']
Теперь запишем a, b и посмотрим, что произойдёт.
a = {'a': 5, 'b': 4, 'c': 8}
b = a
del b['a']
print(b)
print(a)
Результат:
{'b': 4, 'c': 8}
{'b': 4, 'c': 8}
Но что тут произошло? Мы же хотели удалить первый элемент b, а не a …
Решение
Когда мы говорим, что b = a, на самом деле мы имеем в виду, что b
и a
указывают на один и тот же объект. А если оба указывают на один объект, то не имеет значение, выполняем мы операции с b
или a
. Они оба повлияют на этот объект {'a': 5, 'b': 4, 'c': 8}
.
Решение:
import copy
a = {'a': 5, 'b': 4, 'c': 8}
b = copy.copy(a)
del b['a']
print(b)
print(a)
Результат:
{'b': 4, 'c': 8}
{'a': 5, 'b': 4, 'c': 8}
Проблема и решение: присвоение имени файлу
Никогда не присваивайте своим файлам на python названия библиотек, которые вы используете.
Например, если вы назовёте свой файл random.py
, программа просто не поймёт, что вы пытаетесь сделать.
import random
print(random.random())
Результат:
File "C:\Users\HalilibrahimYıldırım\Desktop\medium\Python\random.py", line 3, in <module>
print(random.random())
TypeError: объект 'module' не вызывается
Читайте также:
- Python-библиотеки интерпретации моделей ML
- 30 полезных сниппетов на Python, которые можно освоить за 30 секунд
- Лучшие практики Python для специалистов по обработке данных
Перевод статьи Halil Yıldırım: 3 Common Mistakes You’d Want to Avoid in Python