Telegram Group & Telegram Channel
🐍 Ошибка с изменяемыми значениями по умолчанию»**

🎯 Цель: Найти и объяснить баг, который не вызывает исключений, но ломает логику приложения

📍 Ситуация:

У тебя есть функция, которая логирует события с метаданными. По умолчанию метаданные можно не передавать:


def log_event(event, metadata={}):
metadata["event"] = event
print(metadata)


На первый взгляд — всё работает. Но при многократных вызовах функции происходит что-то странное:


log_event("start")
log_event("stop")
log_event("error", {"code": 500})
log_event("retry")


👀 Вывод:

{'event': 'start'}
{'event': 'stop'}
{'code': 500, 'event': 'error'}
{'code': 500, 'event': 'retry'}


🔍 Что пошло не так? Почему code: 500 появляется там, где его быть не должно?

🧩 Задача:

1. Найди и объясни источник бага
2. Почему Python не выбрасывает ошибку?
3. Как проверить, что дефолтный аргумент сохраняет состояние между вызовами?
4. Как это исправить безопасно и "по питоновски"?
5. Где ещё может проявиться аналогичный эффект?


🛠 Разбор и решение:

🔸 Причина:
Изменяемое значение (`dict`) используется как значение по умолчанию.
В Python значения по умолчанию вычисляются один раз при определении функции, а не при каждом вызове.

То есть metadata={} создаётся один раз и сохраняется между вызовами, если параметр не передан.

🔸 Проверка:

def f(d={}):
print(id(d))
d["x"] = 1
print(d)

f()
f()

Вы увидишь одинаковые id(d) — значит, используется тот же объект.

🔸 Решение (правильный способ):

def log_event(event, metadata=None):
if metadata is None:
metadata = {}
metadata["event"] = event
print(metadata)


Теперь при каждом вызове создаётся новый словарь, и code: 500 не "протекает" в следующие вызовы.

🔸 Где ещё встречается:
- Списки: items=[]
- Множества: visited=set()
- Объекты пользовательских классов

📌 Вывод:
Изменяемые значения по умолчанию — одна из самых частых ошибок в Python. Она не вызывает исключений, но может незаметно повредить данные. Всегда используй None + инициализацию внутри функции для изменяемых типов.



@Python_Community_ru



tg-me.com/Python_Community_ru/2631
Create:
Last Update:

🐍 Ошибка с изменяемыми значениями по умолчанию»**

🎯 Цель: Найти и объяснить баг, который не вызывает исключений, но ломает логику приложения

📍 Ситуация:

У тебя есть функция, которая логирует события с метаданными. По умолчанию метаданные можно не передавать:


def log_event(event, metadata={}):
metadata["event"] = event
print(metadata)


На первый взгляд — всё работает. Но при многократных вызовах функции происходит что-то странное:


log_event("start")
log_event("stop")
log_event("error", {"code": 500})
log_event("retry")


👀 Вывод:

{'event': 'start'}
{'event': 'stop'}
{'code': 500, 'event': 'error'}
{'code': 500, 'event': 'retry'}


🔍 Что пошло не так? Почему code: 500 появляется там, где его быть не должно?

🧩 Задача:

1. Найди и объясни источник бага
2. Почему Python не выбрасывает ошибку?
3. Как проверить, что дефолтный аргумент сохраняет состояние между вызовами?
4. Как это исправить безопасно и "по питоновски"?
5. Где ещё может проявиться аналогичный эффект?


🛠 Разбор и решение:

🔸 Причина:
Изменяемое значение (`dict`) используется как значение по умолчанию.
В Python значения по умолчанию вычисляются один раз при определении функции, а не при каждом вызове.

То есть metadata={} создаётся один раз и сохраняется между вызовами, если параметр не передан.

🔸 Проверка:

def f(d={}):
print(id(d))
d["x"] = 1
print(d)

f()
f()

Вы увидишь одинаковые id(d) — значит, используется тот же объект.

🔸 Решение (правильный способ):

def log_event(event, metadata=None):
if metadata is None:
metadata = {}
metadata["event"] = event
print(metadata)


Теперь при каждом вызове создаётся новый словарь, и code: 500 не "протекает" в следующие вызовы.

🔸 Где ещё встречается:
- Списки: items=[]
- Множества: visited=set()
- Объекты пользовательских классов

📌 Вывод:
Изменяемые значения по умолчанию — одна из самых частых ошибок в Python. Она не вызывает исключений, но может незаметно повредить данные. Всегда используй None + инициализацию внутри функции для изменяемых типов.



@Python_Community_ru

BY Python Community


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/Python_Community_ru/2631

View MORE
Open in Telegram


Python Community Telegram | DID YOU KNOW?

Date: |

The Singapore stock market has alternated between positive and negative finishes through the last five trading days since the end of the two-day winning streak in which it had added more than a dozen points or 0.4 percent. The Straits Times Index now sits just above the 3,060-point plateau and it's likely to see a narrow trading range on Monday.

Telegram announces Anonymous Admins

The cloud-based messaging platform is also adding Anonymous Group Admins feature. As per Telegram, this feature is being introduced for safer protests. As per the Telegram blog post, users can “Toggle Remain Anonymous in Admin rights to enable Batman mode. The anonymized admin will be hidden in the list of group members, and their messages in the chat will be signed with the group name, similar to channel posts.”

Python Community from us


Telegram Python Community
FROM USA