Это фактически не имеет ничего общего с значениями по умолчанию, кроме того, что часто возникает неожиданное поведение при записи функций с изменяемыми значениями по умолчанию.
>>> def foo(a):
a.append(5)
print a
>>> a = [5]
>>> foo(a)
[5, 5]
>>> foo(a)
[5, 5, 5]
>>> foo(a)
[5, 5, 5, 5]
>>> foo(a)
[5, 5, 5, 5, 5]
В этом нет значений по умолчанию код, но вы получаете точно такую же проблему.
Проблема в том, что foo
является изменением изменчивой переменной, переданной от вызывающего, когда вызывающий объект не ожидает этого , Код, подобный этому, был бы хорош, если бы функция была вызвана как-то вроде append_5
; то вызывающий абонент будет вызывать функцию, чтобы изменить значение, которое они передают, и поведение будет ожидаться. Но такая функция вряд ли примет аргумент по умолчанию и, вероятно, не вернет список (поскольку у вызывающего уже есть ссылка на этот список, тот, который он только что передал).
Ваш оригинал foo
с аргументом по умолчанию не должен изменять a
, был ли он явно передан или получил значение по умолчанию. Ваш код должен оставлять изменчивые аргументы отдельно, если из контекста / имени / документации не ясно, что аргументы должны быть изменены. Использование измененных значений, передаваемых в качестве аргументов, таких как локальные временные файлы, является крайне плохой идеей, независимо от того, находимся ли мы на Python или нет, и есть ли задействованные аргументы по умолчанию.
Если вам нужно разрушить локальное временное в процессе вычисления чего-то, и вам нужно начать свою манипуляцию из значения аргумента, вам нужно сделать копию.
В идеале вы должны перейти на MYSQL 8, этот ответ больше предназначен для развлечения
blockquote>Вам нужно написать сложный SQL для имитации / эмуляции MySQL 8.0
JSON_TABLE()
в версиях ниже MySQL 8Запрос
SET @json = '[ { "name":"John Smith", "address":"780 Mission St, San Francisco, CA 94103"}, { "name":"Sally Brown", "address":"75 37th Ave S, St Cloud, MN 94103"}, { "name":"John Johnson", "address":"1262 Roosevelt Trail, Raymond, ME 04071"} ]'; ##SELECT @json; SELECT * FROM JSON_TABLE (@json, '$[*]' COLUMNS ( `name` VARCHAR(40) PATH '$.name', `address` VARCHAR(100) PATH '$.address')) AS T;
Результат
| name | address | | ------------ | --------------------------------------- | | John Smith | 780 Mission St, San Francisco, CA 94103 | | Sally Brown | 75 37th Ave S, St Cloud, MN 94103 | | John Johnson | 1262 Roosevelt Trail, Raymond, ME 04071 |
В MySQL 5.7 запрос имитации / эмуляции включает в себя использование генератора чисел и нескольких собственных функций JSON MySQL.
Запрос
SELECT REPLACE(JSON_EXTRACT(json_record.json, CONCAT('$[',number,'].name')), '"', '') AS name , REPLACE(JSON_EXTRACT(json_record.json, CONCAT('$[',number,'].address')), '"', '') AS address FROM ( SELECT @row := @row + 1 AS number FROM ( SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) row1 CROSS JOIN ( SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) row2 CROSS JOIN ( SELECT @row := -1 ) init_user_params ) AS number_generator CROSS JOIN ( SELECT JSON_LENGTH(json_information.json) - 1 AS json_length , json_information.json FROM ( SELECT record.json FROM ( SELECT ' [{ "name": "John Smith", "address": "780 Mission St, San Francisco, CA 94103" }, { "name": "Sally Brown", "address": "75 37th Ave S, St Cloud, MN 94103" }, { "name": "John Johnson", "address": "1262 Roosevelt Trail, Raymond, ME 04071" }] ' AS json FROM DUAL ) AS record ) AS json_information ) AS json_record WHERE number BETWEEN 0 AND json_length
Результат
| name | address | | ------------ | --------------------------------------- | | John Smith | 780 Mission St, San Francisco, CA 94103 | | Sally Brown | 75 37th Ave S, St Cloud, MN 94103 | | John Johnson | 1262 Roosevelt Trail, Raymond, ME 04071 |
см. демо