Как это работает:
При первом выводе значения, присвоенного имени x, в первой строке функции Python использует значение параметра, объявленного в основном блоке, выше определения функции.
Далее мы назначаем
Последним вызовом функции
При первом выводе значения, присвоенного имени x, в первой строке функции Python использует значение параметра, объявленного в основном блоке, выше определения функции.
Далее мы назначаем
x значение 2. Имя x локально для нашей функции. Поэтому когда мы заменяем значение x в функции, x, объявленный в основном блоке, остаётся незатронутым.Последним вызовом функции
print мы выводим значение x, указанное в основном блоке, подтверждая таким образом, что оно не изменилось при локальном присваивании значения в ранее вызванной функции.Зарезервированное слово “global”
Чтобы присвоить некоторое значение переменной, определённой на высшем уровне программы (т.е. не в какой-либо области видимости, как то функции или классы), необходимо указать Python, что её имя не локально, а глобально (global). Сделаем это при помощи зарезервированного слова
Можно использовать уже существующие значения переменных, определённых за пределами функции (при условии, что внутри функции не было объявлено переменной с таким же именем). Однако, это не приветствуется, и его следует избегать, поскольку человеку, читающему текст программы, будет непонятно, где находится объявление переменной. Использование зарезервированного слова
Чтобы присвоить некоторое значение переменной, определённой на высшем уровне программы (т.е. не в какой-либо области видимости, как то функции или классы), необходимо указать Python, что её имя не локально, а глобально (global). Сделаем это при помощи зарезервированного слова
global. Без применения зарезервированного слова global невозможно присвоить значение переменной, определённой за пределами функции.Можно использовать уже существующие значения переменных, определённых за пределами функции (при условии, что внутри функции не было объявлено переменной с таким же именем). Однако, это не приветствуется, и его следует избегать, поскольку человеку, читающему текст программы, будет непонятно, где находится объявление переменной. Использование зарезервированного слова
global достаточно ясно показывает, что переменная объявлена в самом внешнем блоке.👍1
Пример: (сохраните как func_global.py)
x = 50
def func():
global x
print('x равно', x)
x = 2
print('Заменяем глобальное значение x на', x)
func()
print('Значение x составляет', x)
Вывод:$ python func_global.py
x равно 50
Заменяем глобальное значение x на 2
Значение x составляет 2Как это работает:
Зарезервированное слово global используется для того, чтобы объявить, что x – это глобальная переменная, а значит, когда мы присваиваем значение имени x внутри функции, это изменение отразится на значении переменной x в основном блоке программы.
Используя одно зарезервированное слово global, можно объявить сразу несколько переменных: global x, y, z.
Зарезервированное слово global используется для того, чтобы объявить, что x – это глобальная переменная, а значит, когда мы присваиваем значение имени x внутри функции, это изменение отразится на значении переменной x в основном блоке программы.
Используя одно зарезервированное слово global, можно объявить сразу несколько переменных: global x, y, z.
Зарезервированное слово “nonlocal”
Мы увидели, как получать доступ к переменным в локальной и глобальной области видимости. Есть ещё один тип области видимости, называемый “нелокальной” (nonlocal) областью видимости, который представляет собой нечто среднее между первыми двумя. Нелокальные области видимости встречаются, когда вы определяете функции внутри функций.
Поскольку в Python всё является выполнимым кодом, вы можете определять функции где угодно.
Мы увидели, как получать доступ к переменным в локальной и глобальной области видимости. Есть ещё один тип области видимости, называемый “нелокальной” (nonlocal) областью видимости, который представляет собой нечто среднее между первыми двумя. Нелокальные области видимости встречаются, когда вы определяете функции внутри функций.
Поскольку в Python всё является выполнимым кодом, вы можете определять функции где угодно.
Давайте рассмотрим пример:
# Filename: func_nonlocal.pyВывод:
def func_outer():
x = 2
print('x равно', x)
def func_inner():
nonlocal x
x = 5
func_inner()
print('Локальное x сменилось на', x)
func_outer()
$ python func_nonlocal.py
x равно 2
Локальное x сменилось на 5
Как это работает:
Когда мы находимся внутри func_inner, переменная x, определённая в первой строке func_outer находится ни в локальной области видимости (определение переменной не входит в блок func_inner), ни в глобальной области видимости (она также и не в основном блоке программы). Мы объявляем, что хотим использовать именно эту переменную x, следующим образом: nonlocal x.
Попробуйте заменить “nonlocal x” на “global x”, а затем удалить это зарезервированное слово, и пронаблюдайте за разницей между этими двумя случаями.
Когда мы находимся внутри func_inner, переменная x, определённая в первой строке func_outer находится ни в локальной области видимости (определение переменной не входит в блок func_inner), ни в глобальной области видимости (она также и не в основном блоке программы). Мы объявляем, что хотим использовать именно эту переменную x, следующим образом: nonlocal x.
Попробуйте заменить “nonlocal x” на “global x”, а затем удалить это зарезервированное слово, и пронаблюдайте за разницей между этими двумя случаями.
Значения аргументов по умолчанию
Зачастую часть параметров функций могут быть необязательными, и для них будут использоваться некоторые заданные значения по умолчанию, если пользователь не укажет собственных. Этого можно достичь с помощью значений аргументов по умолчанию. Их можно указать, добавив к имени параметра в определении функции оператор присваивания (=) с последующим значением.
Обратите внимание, что значение по умолчанию должно быть константой. Или точнее говоря, оно должно быть неизменным[1] – это объясняется подробнее в последующих главах. А пока запомните это.
Зачастую часть параметров функций могут быть необязательными, и для них будут использоваться некоторые заданные значения по умолчанию, если пользователь не укажет собственных. Этого можно достичь с помощью значений аргументов по умолчанию. Их можно указать, добавив к имени параметра в определении функции оператор присваивания (=) с последующим значением.
Обратите внимание, что значение по умолчанию должно быть константой. Или точнее говоря, оно должно быть неизменным[1] – это объясняется подробнее в последующих главах. А пока запомните это.
Пример: (сохраните как func_default.py)
def say(message, times = 1):
print(message * times)
say('Привет')
say('Мир', 5)
Вывод:$ python func_default.py
Привет
МирМирМирМирМирКак это работает:
Функция под именем say используется для вывода на экран строки указанное число раз. Если мы не указываем значения, по умолчанию строка выводится один раз. Мы достигаем этого указанием значения аргумента по умолчанию, равного 1 для параметра times[2].
При первом вызове say мы указываем только строку, и функция выводит её один раз. При втором вызове say мы указываем также и аргумент 5, обозначая таким образом, что мы хотим сказать[3] фразу 5 раз.
Функция под именем say используется для вывода на экран строки указанное число раз. Если мы не указываем значения, по умолчанию строка выводится один раз. Мы достигаем этого указанием значения аргумента по умолчанию, равного 1 для параметра times[2].
При первом вызове say мы указываем только строку, и функция выводит её один раз. При втором вызове say мы указываем также и аргумент 5, обозначая таким образом, что мы хотим сказать[3] фразу 5 раз.
Важно: Значениями по умолчанию могут быть снабжены только параметры, находящиеся в конце списка параметров. Таким образом, в списке параметров функции параметр со значением по умолчанию не может предшествовать параметру без значения по умолчанию. Это связано с тем, что значения присваиваются параметрам в соответствии с их положением. Например,
def func(a, b=5) допустимо, а def func(a=5, b) – не допустимо.Ключевые аргументы
Если имеется некоторая функция с большим числом параметров, и при её вызове требуется указать только некоторые из них, значения этих параметров могут задаваться по их имени – это называется ключевые параметры. В этом случае для передачи аргументов функции используется имя (ключ) вместо позиции (как было до сих пор).
Есть два преимущества такого подхода: во-первых, использование функции становится легче, поскольку нет необходимости отслеживать порядок аргументов; во-вторых, можно задавать значения только некоторым избранным аргументам, при условии, что остальные параметры имеют значения аргумента по умолчанию.
Пример: (сохраните как
Функция с именем func имеет один параметр без значения по умолчанию, за которым следуют два параметра со значениями по умолчанию.
При первом вызове, func(3, 7), параметр a получает значение 3, параметр b получает значение 7, а c получает своё значение по умолчанию, равное 10.
При втором вызове func(25, c=24) переменная a получает значение 25 в силу позиции аргумента. После этого параметр c получает значение 24 по имени, т.е. как ключевой параметр. Переменная b получает значение по умолчанию, равное 5.
При третьем обращении func(c=50, a=100) мы используем ключевые аргументы для всех указанных значений. Обратите внимание на то, что мы указываем значение для параметра c перед значением для a, даже несмотря на то, что в определении функции параметр a указан раньше c.
Если имеется некоторая функция с большим числом параметров, и при её вызове требуется указать только некоторые из них, значения этих параметров могут задаваться по их имени – это называется ключевые параметры. В этом случае для передачи аргументов функции используется имя (ключ) вместо позиции (как было до сих пор).
Есть два преимущества такого подхода: во-первых, использование функции становится легче, поскольку нет необходимости отслеживать порядок аргументов; во-вторых, можно задавать значения только некоторым избранным аргументам, при условии, что остальные параметры имеют значения аргумента по умолчанию.
Пример: (сохраните как
func_key.py)def func(a, b=5, c=10):
print('a равно', a, ', b равно', b, ', а c равно', c)
func(3, 7)
func(25, c=24)
func(c=50, a=100)
Вывод:$ python func_key.py
a равно 3, b равно 7, а c равно 10
a равно 25, b равно 5, а c равно 24
a равно 100, b равно 5, а c равно 50
Как это работает:Функция с именем func имеет один параметр без значения по умолчанию, за которым следуют два параметра со значениями по умолчанию.
При первом вызове, func(3, 7), параметр a получает значение 3, параметр b получает значение 7, а c получает своё значение по умолчанию, равное 10.
При втором вызове func(25, c=24) переменная a получает значение 25 в силу позиции аргумента. После этого параметр c получает значение 24 по имени, т.е. как ключевой параметр. Переменная b получает значение по умолчанию, равное 5.
При третьем обращении func(c=50, a=100) мы используем ключевые аргументы для всех указанных значений. Обратите внимание на то, что мы указываем значение для параметра c перед значением для a, даже несмотря на то, что в определении функции параметр a указан раньше c.
Переменное число параметров
Иногда бывает нужно определить функцию, способную принимать любое число параметров. Этого можно достичь при помощи звёздочек (сохраните как
Когда мы объявляем параметр со звёздочкой (например, *param), все позиционные аргументы начиная с этой позиции и до конца будут собраны в кортеж под именем param.
Аналогично, когда мы объявляем параметры с двумя звёздочками (**param), все ключевые аргументы начиная с этой позиции и до конца будут собраны в словарь под именем param.
Мы изучим кортежи и словари в одной из последующих глав.
Иногда бывает нужно определить функцию, способную принимать любое число параметров. Этого можно достичь при помощи звёздочек (сохраните как
function_varargs.py):def total(a=5, *numbers, **phonebook):
print('a', a)
#проход по всем элементам кортежа
for single_item in numbers:
print('single_item', single_item)
#проход по всем элементам словаря
for first_part, second_part in phonebook.items():
print(first_part,second_part)
total(10,1,2,3,Jack=1123,John=2231,Inge=1560)
Вывод:$ python function_varargs.pyКак это работает:
a 10
single_item 1
single_item 2
single_item 3
Inge 1560
John 2231
Jack 1123
None
Когда мы объявляем параметр со звёздочкой (например, *param), все позиционные аргументы начиная с этой позиции и до конца будут собраны в кортеж под именем param.
Аналогично, когда мы объявляем параметры с двумя звёздочками (**param), все ключевые аргументы начиная с этой позиции и до конца будут собраны в словарь под именем param.
Мы изучим кортежи и словари в одной из последующих глав.
Только ключевые параметры
Если некоторые ключевые параметры должны быть доступны только по ключу, а не как позиционные аргументы, их можно объявить после параметра со звёздочкой (сохраните как
Объявление параметров после параметра со звёздочкой даёт только ключевые аргументы. Если для таких аргументов не указано значение по умолчанию, и оно не передано при вызове, обращение к функции вызовет ошибку, в чём мы только что убедились.
Обратите внимание на использование +=, который представляет собой сокращённый оператор, позволяющий вместо x = x + y просто написать x += y.
Если вам нужны аргументы, передаваемые только по ключу, но не нужен параметр со звёздочкой, то можно просто указать одну звёздочку без указания имени: def total(initial=5, *, extra_number).
Если некоторые ключевые параметры должны быть доступны только по ключу, а не как позиционные аргументы, их можно объявить после параметра со звёздочкой (сохраните как
keyword_only.py):def total(initial=5, *numbers, extra_number):
count = initial
for number in numbers:
count += number
count += extra_number
print(count)
total(10, 1, 2, 3, extra_number=50)
total(10, 1, 2, 3)
# Вызовет ошибку, поскольку мы не указали значение
# аргумента по умолчанию для 'extra_number'.
Вывод:$ python keyword_only.py
66
Traceback (most recent call last):
File "keyword_only.py", line 12, in <module>
total(10, 1, 2, 3)
TypeError: total() needs keyword-only argument extra_number
Как это работает:Объявление параметров после параметра со звёздочкой даёт только ключевые аргументы. Если для таких аргументов не указано значение по умолчанию, и оно не передано при вызове, обращение к функции вызовет ошибку, в чём мы только что убедились.
Обратите внимание на использование +=, который представляет собой сокращённый оператор, позволяющий вместо x = x + y просто написать x += y.
Если вам нужны аргументы, передаваемые только по ключу, но не нужен параметр со звёздочкой, то можно просто указать одну звёздочку без указания имени: def total(initial=5, *, extra_number).