PyLint. Что значит dangerous-default-value
Есть следующая функция
def pg_select(sql: str, data: dict = {}) -> list:
"""
SELECT
:param sql: sql-запрос
:param data: Данные sql-запроса. Нужно для того, чтобы избежать sql-injection
:return: None, list
"""
con = psycopg2.connect(user=DB_USER, password=DB_PASSWD,
database=DB_NAME, host=DB_HOST, port=DB_PORT)
cur = con.cursor()
cur.execute(sql, data)
rows = cur.fetchall()
con.close()
return rows
Pylint, встроенный в PyCharm, жалуется на аргумент data, говорит dangerous-default-value
Если позволить ему автоматически исправить код, то получится следующее:
def pg_select(sql: str, data = None) -> list:
"""
SELECT
:param sql: sql-запрос
:param data: Данные sql-запроса. Нужно для того, чтобы избежать sql-injection
:return: None, list
"""
if data is None:
data = {}
con = psycopg2.connect(user=DB_USER, password=DB_PASSWD,
database=DB_NAME, host=DB_HOST, port=DB_PORT)
cur = con.cursor()
cur.execute(sql, data)
rows = cur.fetchall()
con.close()
return rows
Я не понимаю чем опасен мой вариант с data: dict = {}
Объясните: почему правильно делать именно так, как предлагает IDE, в чем заключалась моя ошибка?
Ответы (1 шт):
Аргумент по умолчанию создаётся один раз. Поэтому, если в качестве аргумента по умолчанию выбрать изменяемый тип данных (словарь или список), то он будет общим у всех вызовов функции. Соответственно, если вы один раз вызовете функцию с аргументом по умолчанию и внутри неё в этот аргумент добавите элементы, то они будут там и при следующем вызове этой функции.
Поэтому рекомендуется никогда не использовать в качестве аргумента по умолчанию объект изменяемого типа, чтобы случайно не напороться на такое поведение.