Как получить(вернуть) значение переменной из функции в python 3?

Первый вариант — не слишком хорош т.к. глобальных переменных в большой программе может быть очень много и это приводит к сложностям сопровождения кода программы.
Второй вариант — довольно удобен, но нужно не забывать присваивать значение возвращаемое из функции.
Третий вариант — вообще экзотика, но и он иногда бывает востребован, особенно в рекурсиях или при работе с потоками (когда из потока хочется получить результат).
Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать
Ответы на вопрос 3
Твой последний принт выводит 5 строку, где i остается равной нулю, т.к. она не переопределяется в глобальной области видимости
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать

In Console We Trust. Code hard. Or die.
def fun(i): while i < 3: i=i+1 print (i) return i i = 0 new_i = fun(i) print('='*10, new_i, sep='\n')
global и return
Вы, вероятно, встречали функции с ключевым словом return в конце. Знаете что оно означает? В целом то же самое что и в других языках. Давайте посмотрим на эту маленькую функцию:
def add(value1, value2): return value1 + value2 result = add(3, 5) print(result) # Вывод: 8
Функция выше принимает два значения и возвращает их сумму. Мы также можем переписать её таким образом:
def add(value1,value2): global result result = value1 + value2 add(3, 5) print(result) # Вывод: 8
Как несложно заметить, мы используем глобальную переменную result . Что это означает? К глобальным переменным можно обращаться в том числе и извне области видимости функции. Позвольте продемонстрировать это следующим примером:
# Сначала без глобальной переменной def add(value1, value2): result = value1 + value2 add(2, 4) print(result) # Вот чёрт, мы наткнулись на исключение. Но почему? # Интерпретатор Python говорит нам, что не существует # переменной с именем result. Так произошло, поскольку # переменная result доступна исключительно из функции, # где она была определена, если переменная не является # глобальной. Traceback (most recent call last): File "", line 1, in result NameError: name 'result' is not defined # Попробуем исправить код, сделав result глобальной # переменной def add(value1, value2): global result result = value1 + value2 add(2, 4) print(result) # Вывод: 6
Во второй раз ошибок быть не должно. В реальной жизни от глобальных переменных стоит держаться подальше, они только усложняют жизнь, захламляя глобальную область видимости.
Возврат нескольких значений
Что если мы хотим вернуть две переменные из функции вместо одной? Есть несколько способов, которыми пользуются начинающие разработчики. Первый из них - это использование глобальных переменных. Вот подходящий пример:
def profile(): global name global age name = "Danny" age = 30 profile() print(name) # Вывод: Danny print(age) # Вывод: 30
Примечание: как я уже писал, данный метод использовать не рекомендуется. Повторяю, не используйте вышеуказанный метод!
Другим популярным методом является возврат кортежа, списка или словаря с требуемыми значениями.
def profile(): name = "Danny" age = 30 return (name, age) profile_data = profile() print(profile_data[0]) # Вывод: Danny print(profile_data[1]) # Вывод: 30
Или общепринятое сокращение:
def profile(): name = "Danny" age = 30 return name, age profile_name, profile_age = profile() print(profile_name) # Вывод: Danny print(profile_age) # Вывод: 30
Не забывайте - в примере выше возвращается кортеж (несмотря на отсутствие скобок), а не отдельные значения. Если вы хотите пойти на один шаг дальше, то попробуйте использовать namedtuple. Пример:
from collection import namedtuple def profile(): Person = namedtuple('Person', 'name age') return Person(name="Danny", age=31) # Использование как namedtuple p = profile() print(p, type(p)) # Person(name='Danny', age=31) print(p.name) # Danny print(p.age) # 31 # Использование как простого кортежа p = profile() print(p[0]) # Danny print(p[1]) # 31 # Немедленная распаковка name, age = profile() print(name) # Danny print(age) # 31
Вместе с возвращением списка или словаря кортежи являются лучшим подходом к решению проблемы. Не используйте глобальные переменные, если точно не уверены в том, что делаете. global может быть неплохим вариантом в отдельных редких случаях, но точно не всегда.
Last updated 5 years ago
Как использовать переменную из функции python
Переменные предназначены для хранения данных. Название переменной в Python должно начинаться с алфавитного символа или со знака подчеркивания и может содержать алфавитно-цифровые символы и знак подчеркивания. И кроме того, название переменной не должно совпадать с названием ключевых слов языка Python. Ключевых слов не так много, их легко запомнить:
False await else import pass None break except in raise True class finally is return and continue for lambda try as def from nonlocal while assert del global not with async elif if or yield
Например, создадим переменную:
name = "Tom"
Здесь определена переменная name , которая хранит строку "Tom".
В пайтоне применяется два типа наименования переменных: camel case и underscore notation .
Camel case подразумевает, что каждое новое подслово в наименовании переменной начинается с большой буквы. Например:
userName = "Tom"
Underscore notation подразумевает, что подслова в наименовании переменной разделяются знаком подчеркивания. Например:
user_name = "Tom"
И также надо учитывать регистрозависимость, поэтому переменные name и Name будут представлять разные объекты.
# две разные переменные name = "Tom" Name = "Tom"
Определив переменную, мы можем использовать в программе. Например, попытаться вывести ее содержимое на консоль с помощью встроенной функции print :
name = "Tom" # определение переменной name print(name) # вывод значения переменной name на консоль
Например, определение и применение переменной в среде PyCharm:

Отличительной особенностью переменной является то, что мы можем менять ее значение в течение работы программы:
name = "Tom" # переменной name равна "Tom" print(name) # выводит: Tom name = "Bob" # меняем значение на "Bob" print(name) # выводит: Bob
Типы данных
Переменная хранит данные одного из типов данных. В Python существует множество различных типов данных. В данном случае рассмотрим только самые базовые типы: bool , int , float , complex и str .
Логические значения
Тип bool представляет два логических значения: True (верно, истина) или False (неверно, ложь). Значение True служит для того, чтобы показать, что что-то истинно. Тогда как значение False , наоборот, показывает, что что-то ложно. Пример переменных данного типа:
isMarried = False print(isMarried) # False isAlive = True print(isAlive) # True
Целые числа
Тип int представляет целое число, например, 1, 4, 8, 50. Пример
age = 21 print("Возраст:", age) # Возраст: 21 count = 15 print("Количество:", count) # Количество: 15
По умолчанию стандартные числа расцениваются как числа в десятичной системе. Но Python также поддерживает числа в двоичной, восьмеричной и шестнадцатеричной системах.
Для указания, что число представляет двоичную систему, перед числом ставится префикс 0b :
a = 0b11 b = 0b1011 c = 0b100001 print(a) # 3 в десятичной системе print(b) # 11 в десятичной системе print(c) # 33 в десятичной системе
Для указания, что число представляет восьмеричную систему, перед числом ставится префикс 0o :
a = 0o7 b = 0o11 c = 0o17 print(a) # 7 в десятичной системе print(b) # 9 в десятичной системе print(c) # 15 в десятичной системе
Для указания, что число представляет шестнадцатеричную систему, перед числом ставится префикс 0x :
a = 0x0A b = 0xFF c = 0xA1 print(a) # 10 в десятичной системе print(b) # 255 в десятичной системе print(c) # 161 в десятичной системе
Стоит отметить, что в какой-бы системе мы не передали число в функцию print для вывода на консоль, оно по умолчанию будет выводиться в десятичной системе.
Дробные числа
Тип float представляет число с плавающей точкой, например, 1.2 или 34.76. В качесте разделителя целой и дробной частей используется точка.
height = 1.68 pi = 3.14 weight = 68. print(height) # 1.68 print(pi) # 3.14 print(weight) # 68.0
Число с плавающей точкой можно определять в экспоненциальной записи:
x = 3.9e3 print(x) # 3900.0 x = 3.9e-3 print(x) # 0.0039
Число float может иметь только 18 значимых символов. Так, в данном случае используются только два символа - 3.9. И если число слишком велико или слишком мало, то мы можем записывать число в подобной нотации, используя экспоненту. Число после экспоненты указывает степень числа 10, на которое надо умножить основное число - 3.9.
Комплексные числа
Тип complex представляет комплексные числа в формате вещественная_часть+мнимая_часть j - после мнимой части указывается суффикс j
complexNumber = 1+2j print(complexNumber) # (1+2j)
Строки
Тип str представляет строки. Строка представляет последовательность символов, заключенную в одинарные или двойные кавычки, например "hello" и 'hello'. В Python 3.x строки представляют набор символов в кодировке Unicode
message = "Hello World!" print(message) # Hello World! name = 'Tom' print(name) # Tom
При этом, если строка имеет много символов, ее можно разбить на части и эти части разместить на разных строках кода. В этом случае вся строка заключается в круглые скобки, а ее отдельные части - в кавычки:
text = ("Laudate omnes gentes laudate " "Magnificat in secula ") print(text)
Если же мы хотим определить многострочный текст, то такой текст заключается в тройные двойные или одинарные кавычки:
''' Это комментарий ''' text = '''Laudate omnes gentes laudate Magnificat in secula Et anima mea laudate Magnificat in secula ''' print(text)
При использовани тройных одинарных кавычек не стоит путать их с комментариями: если текст в тройных одинарных кавычках присваивается переменной, то это строка, а не комментарий.
Управляющие последовательности в строке
Строка может содержать ряд специальных символов - управляющих последовательностей. Некоторые из них:
- \\ : позволяет добавить внутрь строки слеш
- \' : позволяет добавить внутрь строки одинарную кавычку
- \" : позволяет добавить внутрь строки двойную кавычку
- \n : осуществляет переход на новую строку
- \t : добавляет табуляцию (4 отступа)
Применим несколько последовательностей:
text = "Message:\n\"Hello World\"" print(text)
Консольный вывод программы:
Message: "Hello World"
Хотя подобные последовательности могут нам помочь в некоторых делах, например, поместить в строку кавычку, сделать табуляцию, перенос на другую строку. Но они также могут и мешать. Например:
path = "C:\python\name.txt" print(path)
Здесь переменная path содержит некоторый путь к файлу. Однако внутри строки встречаются символы "\n", которые будут интерпретированы как управляющая последовательность. Так, мы получим следующий консольный вывод:
C:\python ame.txt
Чтобы избежать подобной ситуации, перед строкой ставится символ r
path = r"C:\python\name.txt" print(path)
Вставка значений в строку
Python позволяет встравивать в строку значения других переменных. Для этого внутри строки переменные размещаются в фигурных скобках <>, а перед всей строкой ставится символ f :
userName = "Tom" userAge = 37 user = f"name: age: " print(user) # name: Tom age: 37
В данном случае на место будет вставляться значение переменной userName. Аналогично на вместо будет вставляться значение переменной userAge.
Динамическая типизация
Python является языком с динамической типизацией. А это значит, что переменная не привязана жестко к определенному типу.
Тип переменной определяется исходя из значения, которое ей присвоено. Так, при присвоении строки в двойных или одинарных кавычках переменная имеет тип str . При присвоении целого числа Python автоматически определяет тип переменной как int . Чтобы определить переменную как объект float, ей присваивается дробное число, в котором разделителем целой и дробной части является точка.
При этом в процессе работы программы мы можем изменить тип переменной, присвоив ей значение другого типа:
userId = "abc" # тип str print(userId) userId = 234 # тип int print(userId)
С помощью встроенной функции type() динамически можно узнать текущий тип переменной:
userId = "abc" # тип str print(type(userId)) # userId = 234 # тип int print(type(userId)) #
Основы Python — Функции и Объекты
До сих пор мы видели, как мы можем использовать переменные в Python для хранения различных типов данных, и как мы можем использовать структуры "управления потоком", такие как условия и циклы, чтобы изменить порядок или способ выполнения строк кода. С помощью только этих инструментов мы уже можем начать выражать некоторые довольно сложные логические схемы. Однако, имея только наши текущие инструменты, любой достаточно сложный скрипт начинал бы становиться очень длинным, так как каждый раз, когда мы хотели выполнить определенный процесс, нам приходилось бы переписывать весь его код.
Вот тут-то и появляются функции и классы . Функции позволяют нам инкапсулировать строки кода для создания пользовательских процессов, которые могут быть повторно использованы в любом месте скрипта. Объекты делают эту инкапсуляцию еще одним шагом вперед и заключают в себе не только один процесс, но и несколько связанных процессов, а также локальные переменные, которые могут отслеживать состояние этого объекта.
Функции
Мы уже видели и использовали некоторые функции, такие как type() , str() , .append() , .keys() и range() . Но что такое функции на самом деле?
Как и в математике, функция-это базовая структура, которая может принимать входные данные, выполнять некоторую обработку этих входных данных и возвращать результат. Давайте создадим базовую функцию, которая добавит два к заданному числу и вернет нам результат:
result = inputNumber + 2
Сам по себе этот код будет только определять, что делает функция, но на самом деле не будет выполнять никакого кода. Чтобы выполнить код внутри функции, вы должны вызвать его где-то внутри скрипта и передать ему соответствующие входные данные:
Определение (Definition) функции начинается с ключевого слова def . После этого следует имя функции,которое следует тем же соглашениям об именовании, что и переменные. Внутри круглой скобки после имени функции можно поместить любое количество входных переменных, которые будут переданы функции при ее вызове и доступны в теле функции. При вызове функции можно либо непосредственно передавать значения, либо передавать переменные, внутри которых хранятся значения. Например, этот код вызовет функцию таким же образом:
Здесь значение переменной var , которое в данном случае равно 2 , передается функции addFunction , а затем доступно внутри этой функции через переменную inputNumber . Обратите внимание, что имена двух переменных var и inputNumber не обязательно должны совпадать. Когда значение передается функции, оно образует прямую связь между двумя наборами скобок, которые несут данные.
В этом случае var — это глобальная переменная, которая хранит значение 2 в основном скрипте, в то время как inputNumber — это локальная переменная, которая хранит это значение только на время выполнения этой функции. Таким образом, функции "сворачивают" конкретные задачи и все данные, необходимые для выполнения этой задачи, чтобы ограничить количество глобальных переменных, необходимых в основной функции.
Первая строка, объявляющая функцию и ее входные данные, заканчивается двоеточием , которое должно быть уже знакомо, с остальной частью тела функции, вставленной из первой строки. При необходимости, если вы хотите вернуть значение из функции обратно в основной скрипт, вы можете завершить функцию с помощью ключевого слова return , за которым следует значение или переменная, которую вы хотите вернуть. Как только функция попадет в оператор return , она пропустит остальную часть тела и вернет связанное значение. Это может быть использовано для создания более сложного поведения внутри функции:
return 'Number must be positive!'
result = inputNumber + 2
Вы можете видеть, что в этом случае, если входные данные меньше нуля, условное условие будет выполнено, что приводит к запуску первого оператора return, пропуская остальную часть кода в функции.
Вы можете передать в функцию любое количество входных данных, но количество входных данных всегда должно совпадать между тем, что определено в функции, и тем, что передается в нее при вызове функции. Например, мы можем расширить нашу простую функцию сложения, чтобы принять два числа, которые будут добавлены:
def addTwoNumbers(inputNumber1, inputNumber2):
result = inputNumber1 + inputNumber2
print addTwoNumbers(2, 3)
Вы также можете вернуть несколько значений, построив их в список, а затем извлекая их из возвращаемого списка. Давайте расширим нашу функцию, чтобы возвращать как сложение, так и умножение двух чисел
def twoNumbers(inputNumber1, inputNumber2):
addition = inputNumber1 + inputNumber2
multiplication = inputNumber1 * inputNumber2
return [addition, multiplication]
result = twoNumbers(2, 3)
print 'addition: ' + str(result[0])
print 'multiplication: ' + str(result[1])
Такие функции чрезвычайно полезны для создания эффективного и читаемого кода. Заключая определенные функциональные возможности в пользовательские модули, они позволяют вам (и, возможно, другим) очень эффективно использовать код, а также заставляют вас быть откровенными о различных наборах операций, происходящих в вашем коде. Вы можете видеть, что основное определение функций довольно просто, однако вы можете быстро начать определять более продвинутые логики, где функции вызывают друг друга и передают входы и возвраты очень сложными способами (вы даже можете передать функцию в качестве входных данных в другую функцию, что мы увидим позже в этих учебниках).
Объекты (Классы)
Шаг за пределы программирования с помощью функций — это объектно-ориентированное программирование или ООП. В ООП программы определяются не как список процедур, которые должны выполняться по очереди, а как набор взаимодействующих объектов. В традиционном процедурном подходе программа выполняется и завершается после выполнения всех процедур. С помощью ООП программа работает непрерывно, а объекты взаимодействуют и запускают различные модели поведения, основанные на событиях, происходящих в реальном времени.
Хотя мы не будем слишком углубляться в ООП в рамках этого курса, мы можем использовать некоторые из его принципов для разработки более сложных проектных пространств. Поэтому важно, по крайней мере, ознакомиться с тем, что такое объекты и как мы можем их использовать в самом базовом смысле. Объект в Python называется классом, но эти два слова часто используются взаимозаменяемо. Вы можете представить себе класс как структуру, которая инкапсулирует набор связанных функций (функции, принадлежащие определенным объектам, часто называются "методами" этого объекта) с набором локальных переменных, которые отслеживают состояние этого класса. Вместе эти переменные и методы определяют "поведение" объекта и определяют, как он взаимодействует с другими объектами в программной "среде".
Давайте подумаем об этом в повседневной жизни. Для животного примером метода может быть "бег". Многие вещи могут работать, поэтому определение работы как функции было бы общим и не обязательно относилось бы к тому, кто выполняет работу. С другой стороны, примером класса может быть "собака", которая будет иметь экземпляр метода "бег", а также другие методы, связанные с тем, чтобы быть собакой, такие как "еда" и "лай". Он также будет иметь набор переменных для хранения информации о данной собаке, такой как ее возраст, порода или вес. Другим классом может быть "человек", который будет хранить различные переменные и будет иметь свою собственную версию методов, таких как "бег" и "еда" (но, надеюсь, не "лай").
Давайте определим очень простой класс, чтобы увидеть, как он работает. Мы будем использовать пример счетчика, который будет хранить значение и увеличивать это значение на основе запросов пользователей:
def addToCounter(self, inputValue):
Обратите внимание, что мы снова используем сокращение += для увеличения значения переменной count объекта на входное значение. Чтобы использовать этот класс, нам сначала нужно создать его экземпляр, который мы будем хранить в переменной так же, как и любой другой фрагмент данных:
Как только мы создадим экземпляр класса (называемый "instantiation"), мы сможем запустить методы этого экземпляра и запросить его переменные. Обратите внимание, что общее определение класса — это только конструкция. Все переменные внутри класса применяются только к определенному экземпляру, и методы могут выполняться только в том случае, если они связаны с этим экземпляром. Например:
Сразу же вы заметите некоторые различия между тем, как мы определяем функции и классы. Во-первых, никакие переменные не передаются в первой строке определения, так как ключевое слово class определяет только общую структуру класса. После первой строки вы найдете список переменных, которые являются локальными переменными этого класса, и будете отслеживать данные для отдельных экземпляров. После этого у вас будет коллекция локальных методов (помните, что "методы" - это просто функции, принадлежащие определенному классу), которые определяют функциональность класса. Эти методы определяются так же, как и раньше, за исключением того, что вы видите, что первым вводом всегда является ключевое слово self . Это представляет экземпляр объекта и всегда передается как первый входной сигнал в каждый метод в классе. Это позволяет вам запрашивать локальные переменные экземпляра, как вы можете видеть, что мы делаем с переменной count .
Чтобы вызвать метод внутри класса, вы используете имя переменной, хранящей экземпляр, и используете точечную нотацию " . " для вызова метода. Точка — это в основном ваш путь в экземпляр, а также все его данные и функциональность. Мы уже видели эту точку раньше, например, когда вызывали функцию .append() в списке. Это потому, что список на самом деле является классом сам по себе! Когда вы определяете список, вы фактически создаете экземпляр класса list , который наследует все функциональные возможности этого класса (сумасшествие, правда?). На самом деле в Python существует только небольшая коллекция примитивных типов данных (ints, floats, booleans и некоторые другие), а все остальное определяется как классы в рамках ООП. Даже строки — это специальные классы, которые хранят коллекцию символов.
Кстати, можно также использовать синтаксис " . " для запроса локальных переменных экземпляра класса. Например, если мы хотим найти значение переменной count myCounter , мы можем просто задать его, набрав:
Однако это не рекомендуется, поскольку оно раскрывает конечному пользователю истинное имя локальных переменных. В производственной среде это создало бы серьезные риски для безопасности, но считается плохой практикой даже в частном использовании. Вместо этого рекомендуется создать специальные методы accessor для извлечения значений переменных из экземпляра, как это было сделано с помощью метода getCount() в нашем примере. Еще одно преимущество этой практики (которая называется инкапсуляцией) заключается в том, что код легче поддерживать. Вы можете вносить любые изменения в определение класса, включая изменение имен локальных переменных и того, что они делают. Пока вы поддерживаете функции доступа и они возвращают ожидаемый результат, вам не нужно ничего обновлять в основном коде.
Что касается именования классов, то вы можете следовать тому же правилу, что и именование переменных или функций, однако стандартная практика заключается в том, чтобы прописывать каждое слово, включая первое.
Наконец, в приведенном выше примере каждый экземпляр, который мы делаем из CounterClass , будет запускать счетчик в 0 . Однако что делать, если мы хотим указать, каким должно быть это число, когда мы создаем экземпляр класса? Для этого мы можем реализовать метод __init__() (это два подчеркивания на каждой стороне ‘init’):
def __init__(self, inputValue):
def addToCounter(self, inputValue):