Выводится '
Ni
' в одной строке, затем 'Spam
' в другой, потому что print()
во вложенной функции находит имя в локальной области видимости объемлющей функции, а отображение в конце находит переменную в глобальной области видимости.Выводится '
Spam
', поскольку оператор nonlocal
означает, что присваивание X
внутри вложенной функции изменяет X
в локальной области видимости объемлющей функции. Без этого оператора присваивания классифицировало X
бы как локальную переменную во вложенной функции, делая ее другой переменной; тогда код выводил бы 'Ni
'.Вот что означает отсутствие совмещения имен — присваивание имени аргумента внутри функции не изменяет волшебным образом переменную. Имена аргументов могут изначально разделять передаваемые объекты (по существу они являются указателями на эти объекты), но только временно, когда функция вызывается впервые. После повторения присваивания аргумента связь разрывается.
Так происходит в случае присваивания самим именам аргументов. Когда аргументам передаются изменяемые объекты, подобные спискам и словарям, мы должны осознавать, что изменения на месте таких объектов могут продолжить свое существования после завершения функции, а потому оказывать воздействие на вызывающий код.
Так происходит в случае присваивания самим именам аргументов. Когда аргументам передаются изменяемые объекты, подобные спискам и словарям, мы должны осознавать, что изменения на месте таких объектов могут продолжить свое существования после завершения функции, а потому оказывать воздействие на вызывающий код.
def changer(a, b): # Аргументам присваиваются ссылки на объекты
a = 2 # Изменяет только значение локального имени
b[0] = 'spam' # Изменяет разделяемый объект на месте
X = 1
L = [2, 3]
changer(X, L) # Передача изменяемого и неизменяемого объектов
print(X, L) # X остается прежним, L отличается
X = 1
a = X # Разделяют тот же самый объект в памяти
a = 2 # Переустанавливает только a, значением X по-прежнему будет 1
print(X)
func(**словарь)
передает все пары ключ / значение в словаре как отдельные ключевые аргументы. Неважно, в каком порядке в
dct
указаны элементы: функция распределит их поименно. Такой тип сопоставления аргументов называется «ключевое». foo(first = 1, second = 'Текст') # как интерпретатор видит аргументы
Существует также позиционное сопоставление аргументов
foo(arg1, arg2)
, где аргументы сопоставляются по их положению. Чтобы оно заработало со словарем dct
, придется передать их так:foo(dct['first'], dct['second'])
Что выведет код выше?
Anonymous Quiz
12%
<__main__.MyClass object at 0x...>
16%
<class 'int'>, <class 'list'>
68%
<class 'tuple'>
4%
Error
Инструкция return может возвращать объект любого типа, поэтому с ее помощью можно возвращать сразу несколько значений, упаковав их в кортеж или в коллекцию любого другого типа.
Выглядит так, как будто функция возвращает два значения, но на самом деле – это единственный кортеж, состоящий из двух элементов, а необязательные окружающие скобки просто опущены. После возврата из функции можно использовать операцию присваивания кортежа, чтобы извлечь отдельные элементы. Переменные X и L изменятся после вызова функции, но только потому, что мы явно это предусмотрели.
def multiple(x, y):
x = 2 # Изменяется только локальное имя
y = [3, 4]
return x, y # Новые значения возвращаются в виде кортежа
X = 1
L = [1, 2]
Z = multiple(X, L) # Результаты присваиваются именам в вызывающей программе
print(Z) # (2, [3, 4]) — это кортеж
Выглядит так, как будто функция возвращает два значения, но на самом деле – это единственный кортеж, состоящий из двух элементов, а необязательные окружающие скобки просто опущены. После возврата из функции можно использовать операцию присваивания кортежа, чтобы извлечь отдельные элементы. Переменные X и L изменятся после вызова функции, но только потому, что мы явно это предусмотрели.
Чем отличается сопоставление аргументов функции func(*arg_obj) от func(**arg_obj)?
Anonymous Quiz
11%
* передает словарь, ** — любой итерируемый объект
80%
* передает любой итерируемый объект, ** — словарь
5%
* позволяет сгенерировать значения аргументов, ** — подставляет везде None
4%
Ничем
def func(*имя) # *имя собирает любые добавочные не прошедшие сопоставление аргументы в кортеж, а **имя — в словарь.
В версии Python 3.0 и выше любые обычные аргументы или аргументы со значениями по умолчанию, следующие за формой
*имя
или за единственным символом *
, являются именованными аргументами, которые при вызове функции должны передаваться только по имени.В каком порядке в функции указываются аргументы?
Anonymous Quiz
72%
Позиционные, ключевые, *итерируемый_объект, **словарь
8%
Позиционные, ключевые, **словарь, *итерируемый_объект
9%
Ключевые, позиционные, **словарь, *итерируемый_объект
11%
Порядок неважен