Вы, вероятно, встречали функции с ключевым словом return в конце. Знаете что оно означает? В целом то же самое что и в других языках. Давайте посмотрим на эту маленькую функцию:
Функция выше принимает два значения и возвращает их сумму. Мы также можем переписать её таким образом:
defadd(value1,value2):global result result = value1 + value2add(3, 5)print(result)# Вывод: 8
Как несложно заметить, мы используем глобальную переменную result. Что это означает? К глобальным переменным можно обращаться в том числе и извне области видимости функции. Позвольте продемонстрировать это следующим примером:
# Сначала без глобальной переменнойdefadd(value1,value2): result = value1 + value2add(2, 4)print(result)# Вот чёрт, мы наткнулись на исключение. Но почему?# Интерпретатор Python говорит нам, что не существует# переменной с именем result. Так произошло, поскольку# переменная result доступна исключительно из функции,# где она была определена, если переменная не является# глобальной.Traceback (most recent call last): File "", line 1,in resultNameError: name 'result'isnot defined# Попробуем исправить код, сделав result глобальной# переменнойdefadd(value1,value2):global result result = value1 + value2add(2, 4)print(result)# Вывод: 6
Во второй раз ошибок быть не должно. В реальной жизни от глобальных переменных стоит держаться подальше, они только усложняют жизнь, захламляя глобальную область видимости.
Возврат нескольких значений
Что если мы хотим вернуть две переменные из функции вместо одной? Есть несколько способов, которыми пользуются начинающие разработчики. Первый из них - это использование глобальных переменных. Вот подходящий пример:
defprofile():global nameglobal age name ="Danny" age =30profile()print(name)# Вывод: Dannyprint(age)# Вывод: 30
Примечание: как я уже писал, данный метод использовать не рекомендуется. Повторяю, не используйте вышеуказанный метод!
Другим популярным методом является возврат кортежа, списка или словаря с требуемыми значениями.
defprofile(): name ="Danny" age =30return (name, age)profile_data =profile()print(profile_data[0])# Вывод: Dannyprint(profile_data[1])# Вывод: 30
Или общепринятое сокращение:
defprofile(): name ="Danny" age =30return name, ageprofile_name, profile_age =profile()print(profile_name)# Вывод: Dannyprint(profile_age)# Вывод: 30
Не забывайте - в примере выше возвращается кортеж (несмотря на отсутствие скобок), а не отдельные значения. Если вы хотите пойти на один шаг дальше, то попробуйте использовать namedtuple. Пример:
from collection import namedtupledefprofile(): Person =namedtuple('Person', 'name age')returnPerson(name="Danny", age=31)# Использование как namedtuplep =profile()print(p, type(p))# Person(name='Danny', age=31) <class '__main__.Person'>print(p.name)# Dannyprint(p.age)# 31# Использование как простого кортежаp =profile()print(p[0])# Dannyprint(p[1])# 31# Немедленная распаковкаname, age =profile()print(name)# Dannyprint(age)# 31
Вместе с возвращением списка или словаря кортежи являются лучшим подходом к решению проблемы. Не используйте глобальные переменные, если точно не уверены в том, что делаете. global может быть неплохим вариантом в отдельных редких случаях, но точно не всегда.