Это может быть менее запутанным, если вы подумаете о привязке, которая происходит в выражении параметра оператора 'def'.Когда вы видите 'def closureTest (maxIndex = maxIndex):', это оператор типа 'if' или 'while', за которым следует набор кода, который нужно проанализировать и привязать к функции (вызываемый объект).
Оператор 'def' оценивается в той области, где он найден (концептуально на том же уровне вложенности / отступа).Его выражение параметра объявляет, как аргументы будут сопоставлены с именами в пределах собственной области функции.Любые из тех, которые предоставляют значение по умолчанию (например, maxIndex в ваших примерах), создают объект функции с соответствующим именем параметра, привязанным к какому-либо объекту, который был назван или создан в то время (в рамках действия) оператора 'def'.
Когда функция вызывается, каждый из ее параметров (имен в пределах ее области действия) связывается с любыми аргументами, предоставленными функции.Любые необязательные параметры, таким образом, оставляются привязанными к тому, какие аргументы были оценены как часть оператора def.
Во всех ваших примерах внутренняя функция создается во время каждого вызова внешней функции.Во втором примере список параметров пуст, а внутренняя функция просто просматривает имя через один уровень вложенной области видимости.В первом примере инструкция def внутренней функции создает имя maxIndex по умолчанию в пределах пространства имен новой функции (таким образом предотвращая любое разрешение имени со значениями из окружающей области, как и следовало ожидать для любой локальной переменной в пределахлюбая функция).
В последнем примере значение maxIndex модифицируется до того, как внутренняя функция (пере) определена.Когда вы понимаете, что функция определяется (пере) определяется при каждом вызове внешней функции, это не должно казаться таким хитрым.
Python - динамический язык.'def' - это оператор, выполняемый виртуальной машиной каждый раз, когда поток управления проходит через эту строку вашего кода.(Да, код был скомпилирован байтами, но 'def' скомпилирован в коды операций VM, которые выполняют оценку кода и привязку имени (к имени функции) во время выполнения).
Если вы определяете функциюсо списком параметров, таким как '(myList = list ())', тогда список будет создан при выполнении определения.Он будет доступен из вызовов кода функции каждый раз, когда функция вызывается без аргументов.Любой вызов с аргументом будет выполнен с этим именем параметра, связанным с аргументом, предоставленным при вызове.(На объект, созданный во время def, все еще ссылается объект кода, который был определен - набор с отступом после оператора def).
Ничего из этого не будет иметь никакого смысла, если вы не сохраните различие междупараметры и аргументы.Помните, что параметры являются частью определения функции;они определяют, как аргументы будут отображаться в локальное пространство имен функции.Аргументы являются частью вызова;это те вещи, которые передаются при любом вызове функции.
Надеюсь, это поможет.Я понимаю, что это различие тонкое и термины очень часто используются неправильно, как если бы они были взаимозаменяемыми (в том числе в документации Python).