Return python: Возврат значений из функции. Оператор return. Курс «Python. Введение в программирование»
Содержание
Возврат значений из функции. Оператор return. Курс «Python. Введение в программирование»
Функции могут передавать какие-либо данные из своих тел в основную ветку программы. Говорят, что функция возвращает значение. В большинстве языков программирования, в том числе Python, выход из функции и передача данных в то место, откуда она была вызвана, выполняется оператором return
.
Если интерпретатор Питона, выполняя тело функции, встречает return
, то он «забирает» значение, указанное после этой команды, и «уходит» из функции.
def cylinder(): r = float(input()) h = float(input()) # площадь боковой поверхности цилиндра: side = 2 * 3.14 * r * h # площадь одного основания цилиндра: circle = 3.14 * r**2 # полная площадь цилиндра: full = side + 2 * circle return full square = cylinder() print(square)
Пример выполнения:
В данной программе в основную ветку из функции возвращается значение локальной переменной full. Не сама переменная, а ее значение, в данном случае – какое-либо число, полученное в результате вычисления площади цилиндра.
В основной ветке программы это значение присваивается глобальной переменной square. То есть выражение square = cylinder()
выполняется так:
Вызывается функция
cylinder()
.Из нее возвращается значение.
Это значение присваивается переменной square.
Не обязательно присваивать результат переменной, его можно сразу вывести на экран:
Здесь число, полученное из cylinder()
, непосредственно передается функции print()
. Если мы в программе просто напишем cylinder()
, не присвоив полученные данные переменной или не передав их куда-либо дальше, то эти данные будут потеряны. Но синтаксической ошибки не будет.
В функции может быть несколько операторов return
. Однако всегда выполняется только один из них. Тот, которого первым достигнет поток выполнения. Допустим, мы решили обработать исключение, возникающее на некорректный ввод. Пусть тогда в ветке except
обработчика исключений происходит выход из функции без всяких вычислений и передачи значения:
def cylinder(): try: r = float(input()) h = float(input()) except ValueError: return side = 2 * 3.14 * r * h circle = 3.14 * r**2 full = side + 2 * circle return full print(cylinder())
Если попытаться вместо цифр ввести буквы, то сработает return
, вложенный в except
. Он завершит выполнение функции, так что все нижеследующие вычисления, в том числе return full
, будут опущены. Пример выполнения:
Но постойте! Что это за слово None
, которое нам вернул «пустой» return
? Это ничего, такой объект – «ничто». Он принадлежит классу NoneType
. До этого мы знали четыре типа данных, они же четыре класса: int
, float
, str
, bool
. Пришло время пятого.
Когда после return
ничего не указывается, то по умолчанию считается, что там стоит объект None. Но никто вам не мешает явно написать return None
.
Более того. Ранее мы рассматривали функции, которые вроде бы не возвращали никакого значения, потому что в них не было оператора return
. На самом деле возвращали, просто мы не обращали на него внимание, не присваивали никакой переменной и не выводили на экран. В Python всякая функция что-либо возвращает. Если в ней нет оператора return
, то она возвращает None
. То же самое, как если в ней имеется «пустой» return
.
Возврат нескольких значений
В Питоне позволительно возвращать из функции несколько объектов, перечислив их через запятую после команды return
:
def cylinder(): r = float(input()) h = float(input()) side = 2 * 3.14 * r * h circle = 3.14 * r**2 full = side + 2 * circle return side, full sCyl, fCyl = cylinder() print("Площадь боковой поверхности %.2f" % sCyl) print("Полная площадь %.2f" % fCyl)
Из функции cylinder()
возвращаются два значения. Первое из них присваивается переменной sCyl, второе – fCyl. Возможность такого группового присвоения – особенность Python, обычно не характерная для других языков:
>>> a, b, c = 10, 15, 19 >>> a 10 >>> b 15 >>> c 19
Фокус здесь в том, что перечисление значений через запятую (например, 10, 15, 19
) создает объект типа tuple
. На русский переводится как «кортеж». Это разновидность структур данных, которые будут изучены позже.
Когда же кортеж присваивается сразу нескольким переменным, то происходит сопоставление его элементов соответствующим в очереди переменным. Это называется распаковкой.
Таким образом, когда из функции возвращается несколько значений, на самом деле из нее возвращается один объект класса tuple
. Перед возвратом эти несколько значений упаковываются в кортеж. Если же после оператора return
стоит только одна переменная или объект, то ее/его тип сохраняется как есть.
Распаковка не является обязательной. Будет работать и так:
Пример выполнения:
На экран выводится кортеж, о чем говорят круглые скобки. Его также можно присвоить одной переменной, а потом вывести ее значение на экран.
Практическая работа
Напишите программу, в которой вызывается функция, запрашивающая с ввода две строки и возвращающая в программу результат их конкатенации. Выведите результат на экран.
Напишите функцию, которая считывает с клавиатуры числа и перемножает их до тех пор, пока не будет введен 0. Функция должна возвращать полученное произведение. Вызовите функцию и выведите на экран результат ее работы.
Примеры решения и дополнительные уроки в android-приложении и pdf-версии курса
Какова цель утверждения return? — CodeRoad
Подумайте о том, что оператор print вызывает побочный эффект , он заставляет вашу функцию записывать некоторый текст пользователю, но он не может быть использован другой функцией.
Я попытаюсь объяснить это лучше с помощью нескольких примеров и пары определений из Википедии.
Вот определение функции из Википедии
Функция в математике связывает одну величину, аргумент функции, также известный как вход, с другой величиной, значением функции, также известным как выход..
Подумайте об этом на секунду. Что это значит, когда вы говорите, что функция имеет значение?
Это означает, что вы действительно можете заменить значение функции нормальным значением! (Предполагая, что эти два значения являются одним и тем же типом значения)
Зачем тебе это нужно, спрашиваешь ты?
А как насчет других функций, которые могут принимать в качестве входных данных значения того же типа ?
def square(n):
return n * n
def add_one(n):
return n + 1
print square(12)
# square(12) is the same as writing 144
print add_one(square(12))
print add_one(144)
#These both have the same output
Существует причудливый математический термин для функций, которые зависят только от своих входных данных для получения своих выходных данных: ссылочная прозрачность. Опять же, определение из Википедии.
Ссылочная прозрачность и ссылочная непрозрачность — это свойства частей компьютерных программ. Выражение считается референциально прозрачным, если его можно заменить на его значение без изменения поведения программы
Возможно, Вам будет немного трудно понять, что это значит, если вы просто новичок в программировании, но я думаю, что вы поймете это после некоторых экспериментов.
Однако в целом вы можете делать такие вещи, как печать в функции, а также иметь оператор return в конце.
Просто помните, что когда вы используете return, вы в основном говорите: «вызов этой функции — это то же самое, что запись возвращаемого значения»
Python на самом деле вставит для вас значение return, если вы откажетесь вставить свое собственное, оно называется «None», и это особый тип, который просто ничего не значит, или null.
Зачем использовать оператор return в Python? Ru Python
Какое простое базовое объяснение того, что такое оператор return, как его использовать в Python?
И в чем разница между ним и заявлением на print
?
Функция print()
записывает, т. Е. «Печатает», строку в консоли. Оператор return
заставляет вашу функцию выйти и передать значение вызывающему. Точка функций в общем случае заключается в том, чтобы принимать входные данные и что-то возвращать. Оператор return
используется, когда функция готова вернуть значение своему вызывающему.
Например, вот функция, использующая print()
и return
:
def foo(): print("hello from inside of foo") return 1
Теперь вы можете запустить код, который вызывает foo, например:
if __name__ == '__main__': print("going to call foo") x = foo() print("called foo") print("foo returned " + str(x))
Если вы запустите это как скрипт (например, файл .py
), а не интерпретатор Python, вы получите следующий вывод:
going to call foo hello from inside foo called foo foo returned 1
Надеюсь, это станет более ясным. Интерпретатор записывает возвращаемые значения в консоль, чтобы я мог понять, почему кого-то можно смутить.
Вот еще один пример из интерпретатора, который демонстрирует:
>>> def foo(): ... print("hello from within foo") ... return 1 ... >>> foo() hello from within foo 1 >>> def bar(): ... return 10 * foo() ... >>> bar() hello from within foo 10
Вы можете видеть, что когда foo()
вызывается из bar()
, 1 не записывается в консоль. Вместо этого он используется для вычисления значения, возвращаемого из bar()
.
print()
– это функция, вызывающая побочный эффект (она записывает строку в консоли), но выполнение возобновляется с помощью следующего оператора. return
заставляет функцию прекратить выполнение и передать значение обратно к вызываемому.
Я думаю, что словарь – это ваша лучшая ссылка здесь
Возвращение и печать
Вкратце:
return возвращает что-то назад или отвечает вызывающей функции, а печать выводит текст
Подумайте о том, что заявление о печати вызывает побочный эффект , что заставляет вашу функцию записывать текст пользователю, но он не может использоваться другой функцией.
Я попытаюсь объяснить это лучше с помощью некоторых примеров и нескольких определений из Википедии.
Вот определение функции из Википедии
Функция в математике связывает одну величину, аргумент функции, также известный как вход, с другой величиной, значением функции, также известной как выход.
Подумайте об этом на секунду. Что означает, когда вы говорите, что функция имеет значение?
Это означает, что вы можете фактически заменить значение функции нормальным значением! (Предполагая, что два значения являются одним и тем же типом значения)
Зачем вам это нужно?
Как насчет других функций, которые могут принимать тот же тип значения, что и вход ?
def square(n): return n * n def add_one(n): return n + 1 print square(12) # square(12) is the same as writing 144 print add_one(square(12)) print add_one(144) #These both have the same output
Существует математический термин для функций, которые зависят только от их входных данных для получения их результатов: Референтная прозрачность. Опять же, определение из Википедии.
Ссылочная прозрачность и ссылочная непрозрачность – это свойства частей компьютерных программ. Выражение называется ссылочно прозрачным, если его можно заменить его значением без изменения поведения программы
Может быть, немного сложно понять, что это значит, если вы просто новичок в программировании, но я думаю, вы получите его после некоторых экспериментов. В общем, вы можете делать такие вещи, как печать в функции, и вы также можете иметь оператор возврата в конце.
Просто помните, что когда вы используете возврат, вы в основном говорите: «Вызов этой функции совпадает с записью возвращаемого значения»
Python фактически введет для вас возвращаемое значение, если вы откажетесь вставить его, оно называется «None», и это особый тип, который просто ничего не значит или null.
В python мы начинаем определять функцию с «def» и заканчиваем функцию «return».
Функция переменной x обозначается как f (x). Что делает эта функция? Предположим, что эта функция добавляет 2 к x. Итак, f (x) = x + 2
Теперь код этой функции будет:
def A_function (x): return x + 2
После определения функции вы можете использовать ее для любой переменной и получить результат. Такие как:
print A_function (2) >>> 4
Мы могли бы просто написать код несколько иначе, например:
def A_function (x): y = x + 2 return y print A_function (2)
Это также даст «4».
Теперь мы можем использовать этот код:
def A_function (x): x = x + 2 return x print A_function (2)
Это также даст 4. Посмотрите, что «x» рядом с возвратом фактически означает (x + 2), а не x «A_function (x)».
Я думаю, из этого простого примера вы поняли смысл команды return.
return
, «выводит это значение из этой функции».
print
«, отправьте это значение в (обычно) stdout»
В REPL Python функция return будет выводиться на экран по умолчанию (это не совсем то же самое, что и печать).
Это пример печати:
>>> n = "foo\nbar" #just assigning a variable. No output >>> n #the value is output, but it is in a "raw form" 'foo\nbar' >>> print n #the \n is now a newline foo >>>
Это пример возврата:
>>> def getN(): ... return "foo\nbar" ... >>> getN() #When this isn't assigned to something, it is just output 'foo\nbar' >>> n = getN() # assigning a variable to the return value. No output >>> n #the value is output, but it is in a "raw form" 'foo\nbar' >>> print n #the \n is now a newline foo bar >>>
Просто чтобы добавить к превосходному ответу @ Натана Хьюза:
Оператор return
может использоваться как своего рода поток управления. Поместив один (или более) оператор return
в середину функции, мы можем сказать: «прекратите выполнение этой функции. У нас либо есть то, что мы хотели, либо что-то пошло не так!»
Вот пример:
>>> def make_3_characters_long(some_string): ... if len(some_string) == 3: ... return False ... if str(some_string) != some_string: ... return "Not a string!" ... if len(some_string) < 3: ... return ''.join(some_string,'x')[:,3] ... return some_string[:,3] ... >>> threechars = make_3_characters_long('xyz') >>> if threechars: ... print threechars ... else: ... print "threechars is already 3 characters long!" ... threechars is already 3 characters long!
Подробнее о том, как использовать return
. В разделе « Стиль кода» руководства Python.
Различие между «возвратом» и «печатью» также можно найти в следующем примере:
ВЕРНУТЬ:
def bigger(a, b): if a > b: return a elif a <b: return b else: return a
Вышеприведенный код даст правильные результаты для всех входов.
РАСПЕЧАТАТЬ:
def bigger(a, b): if a > b: print a elif a <b: print b else: print a
ПРИМЕЧАНИЕ. Это не удастся для многих тестовых случаев.
ОШИБКА:
----
FAILURE
: Test case input: 3, 8.
Expected result: 8
FAILURE
: Test case input: 4, 3.
Expected result: 4
FAILURE
: Test case input: 3, 3.
Expected result: 3
You passed 0 out of 3 test cases
Вот мое понимание. (надеюсь, что это поможет кому-то, и это правильно).
def count_number_of(x): count = 0 for item in x: if item == "what_you_look_for": count = count + 1 return count
Таким образом, эта простая часть кода подсчитывает количество случаев чего-то. Размещение возврата является значительным. Он сообщает вашей программе, где вам нужно значение. Поэтому, когда вы печатаете, вы отправляете вывод на экран. Когда вы вернетесь, вы скажете, что нужно куда-то идти. В этом случае вы можете видеть, что count = 0 с отступом с возвратом – мы хотим, чтобы значение (count + 1) заменило 0. Если вы попытаетесь следовать логике кода, когда вы отступаете от команды возврата, результат будет всегда равным 1 , потому что мы никогда не будем указывать начальный счет для изменения. Надеюсь, у меня все получилось. О, и возврат всегда внутри функции.
Случаи, которые не обсуждались выше.
Оператор return позволяет вам прекратить выполнение функции до того, как вы достигнете конца. Поток выполнения немедленно возвращается к вызывающему.
В строке № 9:
def ret(n): if n > 9: temp = "two digits" return temp #Line 4 else : temp = "one digit" return temp #Line 8 return #Line 9 print ("return statement") ret(10)
После выполнения условного оператора функция ret () прекращается из-за возврата (строка 9). Таким образом, print («return statement») не выполняется.
output : two digits
Этот код, который появляется после оператора возврата или места, в котором поток управления не достигнут, является мертвым кодом .
Возвращаемые значения
В строках 4 и 8 оператор return используется для возврата значения временной переменной после выполнения условия.
Чтобы выявить разницу между печатью и возвратом :
def ret(n): if n > 9: print("two digits") return "two digits" else : print("one digit") return "one digit" return ret(25) output : two digits 'two digits'
return
является частью определения функции, а print
выводит текст на стандартный вывод (обычно на консоль).
Функция – это процедура, принимающая параметры и возвращающая значение. return
для последнего, а первый – def
.
Пример:
def timestwo(x): return x*2
return
должен использоваться для рекурсивных функций / методов или вы хотите использовать возвращаемое значение для последующих приложений в вашем алгоритме.
print
должна использоваться, когда вы хотите отобразить значимый и желаемый результат для пользователя, и вы не хотите загромождать экран промежуточными результатами, которые пользователь не интересует, хотя они полезны для отладки вашего кода.
Следующий код показывает, как правильно использовать return
и print
:
def fact(x): if x < 2: return 1 return x * fact(x - 1) print(fact(5))
Это объяснение справедливо для всех языков программирования, а не только для python .
Лучшая вещь о функции return
– вы можете вернуть значение из функции, но вы можете сделать то же самое с print
так что разница? В принципе, return
не к простому возврату дает результат в форме объекта, так что мы можем сохранить это возвращаемое значение из функции в любую переменную, но мы не можем делать с print
потому что это то же самое, что и stdout/cout
в C Programming
на языке C Programming
Ниже приведен код для лучшего понимания
def add(a, b): print "ADDING %d + %d" % (a, b) return a + b def subtract(a, b): print "SUBTRACTING %d - %d" % (a, b) return a - b def multiply(a, b): print "MULTIPLYING %d * %d" % (a, b) return a * b def divide(a, b): print "DIVIDING %d / %d" % (a, b) return a / b print "Let's do some math with just functions!" age = add(30, 5) height = subtract(78, 4) weight = multiply(90, 2) iq = divide(100, 2) print "Age: %d, Height: %d, Weight: %d, IQ: %d" % (age, height, weight, iq) # A puzzle for the extra credit, type it in anyway. print "Here is a puzzle." what = add(age, subtract(height, multiply(weight, divide(iq, 2)))) print "That becomes: ", what, "Can you do it by hand?"
Теперь мы делаем собственные математические функции для add, subtract, multiply,
и divide
. Важно отметить последнюю строку, где мы говорим return a + b
(в add
). Это делает следующее:
- Наша функция вызывается с двумя аргументами:
a
иb
. - Мы печатаем, что делает наша функция, в данном случае «ДОБАВИТЬ».
- Затем мы говорим Python делать что-то вроде обратного: мы возвращаем добавление
a + b
. Вы можете сказать это так: «Я добавляюa
иb
затем возвращаю их». - Python добавляет два числа. Затем, когда функция заканчивается, любая строка, которая ее запускает, сможет присвоить этот результат
a + b
переменной.
global и return — Intermediate Python
Вы, вероятно, встречали функции с ключевым словом return
в конце. Знаете что оно означает? В целом то же самое что и в других языках. Давайте посмотрим на эту маленькую функцию:
def add(value1, value2):
return value1 + value2
result = add(3, 5)
print(result)
Функция выше принимает два значения и возвращает их сумму. Мы также можем переписать её таким образом:
def add(value1,value2):
global result
result = value1 + value2
add(3, 5)
print(result)
Как несложно заметить, мы используем глобальную переменную result
. Что это означает? К глобальным переменным можно обращаться в том числе и извне области видимости функции. Позвольте продемонстрировать это следующим примером:
def add(value1, value2):
result = value1 + value2
add(2, 4)
print(result)
Traceback (most recent call last):
File "", line 1, in
result
NameError: name 'result' is not defined
def add(value1, value2):
global result
result = value1 + value2
add(2, 4)
print(result)
Во второй раз ошибок быть не должно. В реальной жизни от глобальных переменных стоит держаться подальше, они только усложняют жизнь, захламляя глобальную область видимости.
Что если мы хотим вернуть две переменные из функции вместо одной? Есть несколько способов, которыми пользуются начинающие разработчики. Первый из них — это использование глобальных переменных. Вот подходящий пример:
def profile():
global name
global age
name = "Danny"
age = 30
profile()
print(name)
print(age)
Примечание: как я уже писал, данный метод использовать не рекомендуется. Повторяю, не используйте вышеуказанный метод!
Другим популярным методом является возврат кортежа, списка или словаря с требуемыми значениями.
def profile():
name = "Danny"
age = 30
return (name, age)
profile_data = profile()
print(profile_data[0])
print(profile_data[1])
Или общепринятое сокращение:
def profile():
name = "Danny"
age = 30
return name, age
profile_name, profile_age = profile()
print(profile_name)
print(profile_age)
Не забывайте — в примере выше возвращается кортеж (несмотря на отсутствие скобок), а не отдельные значения. Если вы хотите пойти на один шаг дальше, то попробуйте использовать namedtuple. Пример:
from collection import namedtuple
def profile():
Person = namedtuple('Person', 'name age')
return Person(name="Danny", age=31)
p = profile()
print(p, type(p))
print(p.name)
print(p.age)
p = profile()
print(p[0])
print(p[1])
name, age = profile()
print(name)
print(age)
Вместе с возвращением списка или словаря кортежи являются лучшим подходом к решению проблемы. Не используйте глобальные переменные, если точно не уверены в том, что делаете. global
может быть неплохим вариантом в отдельных редких случаях, но точно не всегда.
Возврат по умолчанию — Python
Рассмотрим немного модифицированную функцию из предыдущего урока:
def sub(a, b):
# Полученный результат никак не используется
# и не возвращается наружу
answer = a - b
result = sub(10, 7)
print(result)
Этот код не содержит синтаксических ошибок, и интерпретатор выполнит его. Но на экран выведется строка None
! В функции нет return
, но несмотря на это, код отработал и в переменную result
записалось что-то.
Держитесь, мы снова повторяем мантру: вызов функции — это выражение, а выражения всегда возвращают результат своего выполнения. Значит, функция всегда возвращает что-то.
Во многих языках программирования есть специальный тип данных с единственным значением: None
(или null
, nil
— названия типа и значения в разных языках различаются). Этот тип используется в ситуациях, когда значение чего-либо не определено.
Так вот, если в функции нет инструкции return
, то интерпретатор Python автоматически возвращает None
. Поэтому в переменную result
записался None
.
Но, конечно, смысла в этой программе нет — функция сейчас не делает ничего полезного. Давайте добавим return
:
def sub(a, b):
answer = a - b
return answer
result = sub(10, 7)
print(result)
Теперь всё работает как надо.
Забыть инструкцию return
— частая ошибка новичка. Мы в обучении каждый день сталкиваемся с просьбами о помощи типа «функция правильная, но почему-то не работает». И почти всегда оказывается, что забыт return
, а результат, вместо возврата, просто печатается на экран.
Кстати, вы можете сами написать return None
в теле функции. Функция будет возвращать None
, как если бы в ней не было return
.
Вопрос для самопроверки. Что возвращает функция print()
?
Задание
Это немного странное задание, но для тренировки будет полезным. Реализуйте функцию get_none()
, не имеющую параметров и всегда возвращающую None
. Больше функция ничего делать не должна — вот такая она странная! И возвращайте None
самостоятельно, не ждите, что Python это сделает за вас — в этом и суть данной тренировки!
Вам не нужно вызывать свою функцию, только определить её.
Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Язык программирования «Python». Возвращаемое значение функции. Оператор return
40. Возвращаемое значение функции. Оператор return
41. Область видимости: локальная, глобальная и встроенная.
42. Вложенные функции Python
43. Замыкания в Python. Closure Python
44. Замыкания в Python Часть 2
45. Передача аргументов. Сопоставление аргументов по имени и позиции
46. *args и **kwargs Python. Передача аргументов в функцию
47. Рекурсия в Python. Рекурсивная функция Часть 1
48. Рекурсия в Python. Рекурсивная функция Часть 2
Сравнение операторов yield и return в Python (с примерами)
В этой статье мы расскажем про основные различия между yield и return в Python. А для лучшего понимания этих различий приведем пару примеров.
Встроенное ключевое слово yield используется для создания функций-генераторов. (Про генераторы и их отличия от функций и списков можно подробнее прочитать здесь).
Функция, содержащая yield, может генерировать сразу несколько результатов. Она приостанавливает выполнение программы, отправляет значение результата вызывающей стороне и возобновляет выполнение с последнего yield. Кроме того, функция, содержащая yield, отправляет сгенерированную серию результатов в виде объекта-генератора.
Return также является встроенным ключевым словом в Python. Он завершает функцию, а вызывающей стороне отправляет значение.
Разница между yield и return
Начнем с того, что между yield и return есть много заметных различий. Для начала давайте обсудим их.
return | yield |
---|---|
Оператор return возвращает только одно значение. | Оператор yield может возвращать серию результатов в виде объекта-генератора. |
Return выходит из функции, а в случае цикла он закрывает цикл. Это последний оператор, который нужно разместить внутри функции. | Не уничтожает локальные переменные функции. Выполнение программы приостанавливается, значение отправляется вызывающей стороне, после чего выполнение программы продолжается с последнего оператора yield. |
Логически, функция должна иметь только один return. | Внутри функции может быть более одного оператора yield. |
Оператор return может выполняться только один раз. | Оператор yield может выполняться несколько раз. |
Return помещается внутри обычной функции Python. | Оператор yield преобразует обычную функцию в функцию-генератор. |
Пример 1
Теперь давайте рассмотрим разницу между операторами return и yield на примерах.
В приведенном ниже коде мы использовали несколько операторов возврата. Вы можете заметить, что выполнение программы прекратится уже после первого оператора return. Весь код, идущий после, не будет выполнен.
num1 =10 num2=20 def mathOP(): return num1+num2 return num1-num2 return num1*num2 return num1/num2 print(mathOP())
В выводе видно, что функция возвращает только первое значение, после чего программа завершается.
Чтобы выполнить аналогичную задачу с несколькими операторами return, нам нужно создать четыре разные функции для каждого типа арифметической операции.
num1 =10 num2=20 def sumOP(): return num1+num2 def subtractOP(): return num1-num2 def multiplicationOP(): return num1*num2 def divisionOP(): return num1/num2 print("The sum value is: ",sumOP()) print("The difference value is: ",subtractOP()) print("The multiplication value is: ",multiplicationOP()) print("The division value is: ",divisionOP())
Запустив данный код, получим следующий результат:
Однако мы можем выполнить эти арифметические операции внутри одной функции-генератора, используя несколько операторов yield.
num1 =10 num2=20 def mathOP(): yield num1+num2 yield num1-num2 yield num1*num2 yield num1/num2 print("Printing the values:") for i in mathOP(): print(i)
Получим результат:
Пример 2
Давайте рассмотрим еще один пример использования операторов return и yield.
Создадим список чисел и передадим его в функцию mod()
в качестве аргумента. Далее, внутри функции, мы проверяем каждый элемент списка. Если он делится без остатка на 10, то мы его выводим.
Для начала давайте реализуем этот пример в нашем скрипте Python с использованием оператора return.
myList=[10,20,25,30,35,40,50] def mod(myList): for i in myList: if(i%10==0): return i print(mod(myList))
Оператор return возвращает только первое число, кратное 10, и завершает выполнение функции.
Теперь давайте реализуем тот же пример, используя оператор yield.
myList=[10,20,25,30,35,40,50] def mod(myList): for i in myList: if(i%10==0): yield i for i in mod(myList): print(i)
Получим следующий результат:
Заключение
В этой статье мы провели сравнение yield и return в Python, перечислили все заметные различия между ними и разобрали это на примерах.
Давайте подытожим.
И return, и yield являются встроенными ключевыми словами (или операторами) Python. Оператор return используется для возврата значения из функции. При этом он прекращает выполнение программы. А оператор yield создает объект-генератор и может возвращать несколько значений, не прерывая выполнение программы.
Свежие вакансии по Python
Для тех, кто хочет найти работу Junior Python Developer
Подписаться
×
Использование и передовые методы — Настоящий Python
Оператор возврата Python является ключевым компонентом функций и методов. Вы можете использовать оператор
return
, чтобы ваши функции отправляли объекты Python обратно в вызывающий код. Эти объекты известны как возвращаемое значение функции . Вы можете использовать их для выполнения дальнейших вычислений в ваших программах.
Эффективное использование оператора return
- это ключевой навык, если вы хотите кодировать настраиваемые функции, которые являются питоническими и надежными.
В этом руководстве вы узнаете:
- Как использовать Python
return
statement в ваших функциях - Как вернуть одиночных или множественных значений из ваших функций
- Какие передовые практики соблюдать при использовании
return
statement
Обладая этими знаниями, вы сможете писать на Python более удобочитаемые, удобные в обслуживании и краткие функции. Если вы новичок в функциях Python, вы можете проверить определение своей собственной функции Python перед тем, как погрузиться в это руководство.
Бесплатный бонус: 5 мыслей о Python Mastery, бесплатный курс для разработчиков Python, который показывает вам план действий и образ мышления, который вам понадобится, чтобы вывести свои навыки Python на новый уровень.
Начало работы с функциями Python
Большинство языков программирования позволяют присвоить имя блоку кода, который выполняет конкретное вычисление. Эти именованные блоки кода можно быстро повторно использовать, потому что вы можете использовать их имя для вызова их из разных мест вашего кода.
Программисты называют эти именованные блоки кода подпрограммами , подпрограммами , процедурами или функциями в зависимости от используемого языка. В некоторых языках существует явная разница между рутиной или процедурой и функцией.
Иногда это различие настолько велико, что вам нужно использовать конкретное ключевое слово для определения процедуры или подпрограммы и другое ключевое слово для определения функции. Например, язык программирования Visual Basic использует Sub
и Function
, чтобы различать их.
Обычно процедура представляет собой именованный кодовый блок, который выполняет набор действий без вычисления окончательного значения или результата. С другой стороны, функция - это именованный блок кода, который выполняет некоторые действия с целью вычисления окончательного значения или результата, которые затем отправляются обратно в код вызывающего абонента. И процедуры, и функции могут действовать на набор из входных значений , обычно известных как аргументов .
В Python эти типы именованных блоков кода известны как функции, потому что они всегда отправляют значение обратно вызывающей стороне.В документации Python функция определяется следующим образом:
Серия операторов, возвращающих вызывающему объекту некоторое значение. Ему также можно передать ноль или более аргументов, которые могут использоваться при выполнении тела. (Источник)
Несмотря на то, что в официальной документации указано, что функция «возвращает некоторое значение вызывающей стороне», вы скоро увидите, что функции могут возвращать любой объект Python в код вызывающей стороны.
Обычно функция принимает аргументов (если есть), выполняет некоторых операций, а возвращает значение (или объект).Значение, которое функция возвращает вызывающей стороне, обычно называется возвращаемым значением функции . Все функции Python имеют возвращаемое значение, явное или неявное. О разнице между явным и неявным возвращаемыми значениями вы познакомитесь позже в этом руководстве.
Чтобы написать функцию Python, вам нужен заголовок , который начинается с ключевого слова def
, за которым следует имя функции, необязательный список аргументов, разделенных запятыми, внутри необходимой пары круглых скобок и последнее двоеточие.
Второй компонент функции - это блок кода или тело . Python определяет блоки кода, используя отступы вместо скобок, ключевые слова begin
и end
и так далее. Итак, чтобы определить функцию в Python, вы можете использовать следующий синтаксис:
def имя_функции (arg1, arg2, ..., argN):
# Код функции находится здесь ...
проходить
При кодировании функции Python необходимо определить заголовок с ключевым словом def
, именем функции и списком аргументов в круглых скобках.Обратите внимание, что список аргументов необязателен, но скобки синтаксически обязательны. Затем вам нужно определить блок кода функции, который начнет отступ на один уровень вправо.
В приведенном выше примере вы используете оператор pass
. Этот вид оператора полезен, когда вам нужен оператор-заполнитель в вашем коде, чтобы сделать его синтаксически правильным, но вам не нужно выполнять никаких действий. pass
инструкции также известны как нулевая операция , потому что они не выполняют никаких действий.
Примечание: Полный синтаксис для определения функций и их аргументов выходит за рамки этого руководства. Чтобы получить более подробный ресурс по этой теме, ознакомьтесь с «Определение вашей собственной функции Python».
Чтобы использовать функцию, вам нужно ее вызвать. Вызов функции состоит из имени функции, за которым следуют аргументы функции в круглых скобках:
имя_функции (аргумент1, аргумент2, ..., аргументN)
Вам нужно будет передавать аргументы вызову функции только в том случае, если они требуются функции.С другой стороны, круглые скобки всегда требуются при вызове функции. Если вы их забудете, то вы не будете вызывать функцию, а будете ссылаться на нее как на объект функции.
Чтобы ваши функции возвращали значение, вам нужно использовать оператор Python return
. Это то, что вы рассмотрите с этого момента.
Понимание возврата Python
Заявление
Оператор Python return
- это специальный оператор, который можно использовать внутри функции или метода для отправки результата функции обратно вызывающей стороне.Оператор return
состоит из ключевого слова return
, за которым следует необязательное возвращаемое значение .
Возвращаемое значение функции Python может быть любым объектом Python. Все в Python - это объект. Итак, ваши функции могут возвращать числовые значения ( int
, float
и комплексные
значения), коллекции и последовательности объектов ( список
, кортеж
, словарь
или набор
объектов), пользователь -определенные объекты, классы, функции и даже модули или пакеты.
Вы можете опустить возвращаемое значение функции и использовать пустой return
без возвращаемого значения. Вы также можете опустить весь оператор return
. В обоих случаях возвращаемое значение будет Нет
.
В следующих двух разделах вы познакомитесь с основами того, как работает оператор return
и как вы можете использовать его для возврата результата функции обратно в вызывающий код.
Явный
возврат
Заявления
Явный return
Оператор немедленно завершает выполнение функции и отправляет возвращаемое значение обратно в вызывающий код.Чтобы добавить явный оператор return
к функции Python, вам нужно использовать return
, за которым следует необязательное возвращаемое значение:
>>>
>>> def return_42 ():
... return 42 # Явный оператор возврата
...
>>> return_42 () # Код вызывающего абонента получает 42
42
Когда вы определяете return_42 ()
, вы добавляете явный оператор return
( return 42
) в конце блока кода функции. 42
- явное возвращаемое значение return_42 ()
. Это означает, что каждый раз, когда вы вызываете return_42 ()
, функция отправляет 42
обратно вызывающей стороне.
Примечание: Вы можете использовать явные операторы return
с возвращаемым значением или без него. Если вы создадите оператор return
без указания возвращаемого значения, вы неявно вернете None
.
Если вы определяете функцию с явным оператором return
, который имеет явное возвращаемое значение, то вы можете использовать это возвращаемое значение в любом выражении:
>>>
>>> число = return_42 ()
>>> число
42
>>> return_42 () * 2
84
>>> return_42 () + 5
47
Поскольку return_42 ()
возвращает числовое значение, вы можете использовать это значение в математическом выражении или любом другом виде выражения, в котором значение имеет логическое или связное значение.Вот как вызывающий код может воспользоваться возвращаемым значением функции.
Обратите внимание, что вы можете использовать оператор return
только внутри определения функции или метода. Если вы используете его где-нибудь еще, то получите SyntaxError
:
>>>
>>> возврат 42
Файл "", строка 1
SyntaxError: 'return' вне функции
Когда вы используете return
вне функции или метода, вы получаете SyntaxError
, сообщающее, что оператор не может использоваться вне функции.
В качестве возвращаемого значения можно использовать любой объект Python. Поскольку все в Python является объектами, вы можете возвращать строки, списки, кортежи, словари, функции, классы, экземпляры, определяемые пользователем объекты и даже модули или пакеты.
Например, скажем, вам нужно написать функцию, которая принимает список целых чисел и возвращает список, содержащий только четные числа из исходного списка. Вот способ кодирования этой функции:
>>>
>>> def get_even (числа):
... even_nums = [число вместо числа в числах, если не число% 2]
... вернуть even_nums
...
>>> get_even ([1, 2, 3, 4, 5, 6])
[2, 4, 6]
get_even ()
использует понимание списка для создания списка, который отфильтровывает нечетные числа в исходных числах
. Затем функция возвращает результирующий список, содержащий только четные числа.
Обычной практикой является использование результата выражения в качестве возвращаемого значения в операторе return
.Чтобы применить эту идею, вы можете переписать get_even ()
следующим образом:
>>>
>>> def get_even (числа):
... return [число вместо числа в числах, если не число% 2]
...
>>> get_even ([1, 2, 3, 4, 5, 6])
[2, 4, 6]
Понимание списка оценивается, а затем функция возвращается с результирующим списком. Обратите внимание, что вы можете использовать выражения только в операторе return
. Выражения отличаются от таких операторов, как условные выражения или циклы.
Примечание: Несмотря на то, что понимания списка
построены с использованием для
и (необязательно) если
ключевых слов, они считаются выражениями, а не утверждениями. Вот почему вы можете использовать их в операторе return
.
В качестве следующего примера, скажем, вам нужно вычислить среднее значение выборки числовых значений. Для этого вам нужно разделить сумму значений на количество значений. Вот пример, в котором используются встроенные функции sum ()
и len ()
:
.
>>>
>>> def mean (пример):
... вернуть сумму (образец) / len (образец)
...
>>> среднее ([1, 2, 3, 4])
2,5
В mean ()
вы не используете локальную переменную для хранения результата вычисления. Вместо этого вы используете выражение непосредственно как возвращаемое значение. Python сначала оценивает выражение sum (sample) / len (sample)
, а затем возвращает результат оценки, которым в данном случае является значение 2,5
.
Неявный
возврат
Заявления
Функция Python всегда будет иметь возвращаемое значение.В Python нет понятия процедуры или рутины. Итак, если вы явно не используете возвращаемое значение в операторе return
или полностью опускаете оператор return
, тогда Python неявно вернет вам значение по умолчанию. Это возвращаемое значение по умолчанию всегда будет Нет
.
Допустим, вы пишете функцию, которая добавляет 1
к числу x
, но вы забываете предоставить оператор return
. В этом случае вы получите неявный return
оператор , который использует None
в качестве возвращаемого значения:
>>>
>>> def add_one (x):
... # Никакого возврата
... результат = x + 1
...
>>> значение = add_one (5)
>>> значение
>>> print (значение)
Никто
Если вы не предоставите явный оператор return
с явным возвращаемым значением, тогда Python предоставит неявный оператор return
, используя None
в качестве возвращаемого значения. В приведенном выше примере add_one ()
добавляет 1
к x
и сохраняет значение в result
, но не возвращает result
.Вот почему вы получаете значение = Нет
вместо значения = 6
. Чтобы решить эту проблему, вам нужно либо вернуть результат
, либо напрямую вернуть x + 1
.
Пример функции, которая возвращает Нет
: print ()
. Цель этой функции - распечатать объекты в файл текстового потока, который обычно является стандартным выводом (ваш экран). Таким образом, этой функции не требуется явный оператор return
, потому что он не возвращает ничего полезного или значимого:
>>>
>>> return_value = print ("Привет, мир")
Привет мир
>>> print (return_value)
Никто
При вызове print ()
на экран выводится Hello, World
.Так как это цель print ()
, функция не должна возвращать ничего полезного, поэтому вы получите None
в качестве возвращаемого значения.
Независимо от длины и сложности ваших функций, любая функция без явного оператора return
или функция с оператором return
без возвращаемого значения вернет None
.
Возврат и печать
Если вы работаете в интерактивном сеансе, вы можете подумать, что печать значения и возврат значения являются эквивалентными операциями.Рассмотрим следующие две функции и их результат:
>>>
>>> def print_greeting ():
... print ("Привет, мир")
...
>>> print_greeting ()
Привет мир
>>> def return_greeting ():
... return "Hello, World"
...
>>> return_greeting ()
'Привет мир'
Обе функции, похоже, делают одно и то же. В обоих случаях на экране отображается Hello, World
. Есть только тонкое видимое различие - одинарные кавычки во втором примере.Но посмотрите, что произойдет, если вы вернете другой тип данных, скажем, объект int
:
>>>
>>> def print_42 ():
... печать (42)
...
>>> print_42 ()
42
>>> def return_42 ():
... возврат 42
...
>>> return_42 ()
42
Сейчас видимой разницы нет. В обоих случаях на экране отображается 42
. Такое поведение может сбивать с толку, если вы только начинаете работать с Python. Вы можете подумать, что возврат и печать значения - эквивалентные действия.
Теперь предположим, что вы углубляетесь в Python и начинаете писать свой первый скрипт. Вы открываете текстовый редактор и вводите следующий код:
1def add (a, b):
2 результат = a + b
3 вернуть результат
4
5add (2, 2)
add ()
берет два числа, складывает их и возвращает результат. На , строка 5 , вы звоните добавить ()
, чтобы получить сумму 2
плюс 2
. Поскольку вы все еще изучаете разницу между возвратом и печатью значения, вы можете ожидать, что ваш скрипт выведет на экран 4
.Однако этого не происходит, и на экране ничего не отображается.
Попробуйте сами. Сохраните свой сценарий в файл с именем add.py
и запустите его из командной строки следующим образом:
Если вы запустите add.py
из командной строки, вы не увидите никаких результатов на экране. Это связано с тем, что при запуске сценария возвращаемые значения функций, которые вы вызываете в сценарии, не выводятся на экран, как в интерактивном сеансе.
Если вы хотите, чтобы ваш скрипт отображал результат вызова add ()
на вашем экране, вам необходимо явно вызвать print ()
. Ознакомьтесь со следующим обновлением add.py
:
1def add (a, b):
2 результат = a + b
3 вернуть результат
4
5print (добавить (2, 2))
Теперь, когда вы запустите add.py
, вы увидите на экране число 4
.
Итак, если вы работаете в интерактивном сеансе, Python покажет результат любого вызова функции прямо на ваш экран.Но если вы пишете сценарий и хотите увидеть возвращаемое значение функции, вам нужно явно использовать print ()
.
Возврат нескольких значений
Вы можете использовать оператор return
для возврата нескольких значений из функции. Для этого вам просто нужно указать несколько возвращаемых значений, разделенных запятыми.
Например, предположим, что вам нужно написать функцию, которая берет выборку числовых данных и возвращает сводку статистических показателей.Чтобы закодировать эту функцию, вы можете использовать стандартный модуль Python statistics
, который предоставляет несколько функций для вычисления математической статистики числовых данных.
Вот возможная реализация вашей функции:
статистика импорта как st
def описать (образец):
return st.mean (образец), st.median (образец), st.mode (образец)
В describe ()
вы используете возможность Python возвращать несколько значений в одном операторе return
, одновременно возвращая среднее, медианное значение и режим выборки.Обратите внимание, что для возврата нескольких значений вам просто нужно записать их в список, разделенный запятыми, в том порядке, в котором вы хотите, чтобы они возвращались.
После того, как вы закодировали describe ()
, вы можете воспользоваться мощной функцией Python, известной как итеративная распаковка, чтобы распаковать три меры в три отдельные переменные, или вы можете просто сохранить все в одной переменной:
>>>
>>> sample = [10, 2, 4, 7, 9, 3, 9, 8, 6, 7]
>>> среднее, медиана, режим = описать (образец)
>>> означает
6.5
>>> медиана
7.0
>>> режим
7
>>> desc = описать (образец)
>>> desc
(6.5, 7.0, 7)
>>> тип (по убыванию)
<класс 'кортеж'>
Здесь вы распаковываете три возвращаемых значения describe ()
в переменные mean
, median
и mode
. Обратите внимание, что в последнем примере вы сохраняете все значения в одной переменной desc
, которая оказывается кортежем Python
.
Примечание: Вы можете создать кортеж Python
, просто присвоив одной переменной несколько значений, разделенных запятыми.Для создания кортежа
нет необходимости использовать круглые скобки. Вот почему несколько возвращаемых значений упаковываются в кортеж
.
Встроенная функция divmod ()
также является примером функции, возвращающей несколько значений. Функция принимает два (некомплексных) числа в качестве аргументов и возвращает два числа, частное двух входных значений и остаток от деления:
>>>
>>> divmod (15, 3)
(5, 0)
>>> divmod (8, 3)
(2, 2)
Вызов divmod ()
возвращает кортеж, содержащий частное и остаток, полученные в результате деления двух некомплексных чисел, предоставленных в качестве аргументов.Это пример функции с несколькими возвращаемыми значениями.
Использование Python
return
Заявление: передовой опыт
Итак, вы рассмотрели основы работы оператора Python return
. Теперь вы знаете, как писать функции, возвращающие одно или несколько значений вызывающей стороне. Кроме того, вы узнали, что если вы не добавите явный оператор return
с явным возвращаемым значением для данной функции, Python добавит его за вас.Это значение будет Нет
.
В этом разделе вы рассмотрите несколько примеров, которые проведут вас через набор передовых методов программирования для эффективного использования оператора return
. Эти практики помогут вам писать более удобочитаемые, удобные в обслуживании, надежные и эффективные функции на Python.
Возврат
Нет
Явно
Некоторые программисты полагаются на неявный оператор return
, который Python добавляет к любой функции без явной.Это может сбивать с толку разработчиков, пришедших из других языков программирования, в которых функция без возвращаемого значения называется процедурой .
Существуют ситуации, в которых вы можете добавить к своим функциям явный return None
. Однако в других ситуациях вы можете полагаться на поведение Python по умолчанию:
Если ваша функция выполняет действия, но не имеет четкого и полезного значения
return
, вы можете не возвращатьNone
, потому что это будет излишним и запутанным.Вы также можете использовать голыйreturn
без возвращаемого значения, чтобы прояснить ваше намерение вернуться из функции.Если ваша функция имеет несколько операторов
return
и возвращаетNone
является допустимым вариантом, вам следует рассмотреть явное использованиеreturn None
вместо того, чтобы полагаться на поведение Python по умолчанию.
Эти методы могут улучшить читаемость и ремонтопригодность вашего кода, явно сообщая о ваших намерениях.
Когда дело доходит до возврата Нет
, вы можете использовать один из трех возможных подходов:
- Пропустите оператор
return
и полагайтесь на поведение по умолчанию, возвращающееNone
. - Используйте пустой результат
, возвращаемый
без возвращаемого значения, который также возвращаетНет
. - Вернуть
Нет
явно.
Вот как это работает на практике:
>>>
>>> def omit_return_stmt ():
... # Пропустите оператор возврата
... проходить
...
>>> печать (omit_return_stmt ())
Никто
>>> def bare_return ():
... # Использовать чистый доход
... возвращаться
...
>>> печать (bare_return ())
Никто
>>> def return_none_explicitly ():
... # Явно не возвращать None
... return None
...
>>> print (return_none_explicitly ())
Никто
Возвращать или не возвращать Нет.
явно является личным решением. Однако вы должны учитывать, что в некоторых случаях явный возврат None
может избежать проблем с ремонтопригодностью.Это особенно верно для разработчиков, пришедших из других языков программирования, которые ведут себя не так, как Python.
Запоминание возвращаемого значения
При написании пользовательских функций вы можете случайно забыть вернуть значение из функции. В этом случае Python вернет вам None
. Это может вызвать небольшие ошибки, которые может быть сложно понять и отладить начинающему разработчику Python.
Этой проблемы можно избежать, написав оператор return
сразу после заголовка функции.Затем вы можете сделать второй проход для записи тела функции. Вот шаблон, который вы можете использовать при написании функций Python:
def template_func (аргументы):
result = 0 # Инициализировать возвращаемое значение
# Ваш код находится здесь ...
return result # Явно вернуть результат
Если вы привыкнете запускать свои функции таким образом, то, скорее всего, вы больше не пропустите оператор return
. При таком подходе вы можете написать тело функции, протестировать его и переименовать переменные, как только вы узнаете, что функция работает.
Такой подход может повысить вашу продуктивность и снизить вероятность ошибок в ваших функциях. Это также может сэкономить вам много времени на отладку.
Избегайте сложных выражений
Как вы видели ранее, это обычная практика - использовать результат выражения в качестве возвращаемого значения в функциях Python. Если выражение, которое вы используете, становится слишком сложным, это может привести к появлению функций, которые трудно понять, отладить и поддерживать.
Например, если вы выполняете сложный расчет, было бы удобнее постепенно вычислять окончательный результат, используя временных переменных с понятными именами.
Рассмотрим следующую функцию, которая вычисляет дисперсию выборки числовых данных:
>>>
>>> def variance (data, ddof = 0):
... среднее значение = сумма (данные) / len (данные)
... вернуть сумму ((x - среднее) ** 2 для x в данных) / (len (data) - ddof)
...
>>> дисперсия ([3, 4, 7, 5, 6, 2, 9, 4, 1, 3])
5,24
Выражение, которое вы здесь используете, довольно сложное и трудное для понимания. Отладка также затруднена, потому что вы выполняете несколько операций в одном выражении.Чтобы обойти эту конкретную проблему, вы можете воспользоваться подходом инкрементальной разработки, который улучшает читаемость функции.
Взгляните на следующую альтернативную реализацию variance ()
:
>>>
>>> def variance (data, ddof = 0):
... n = len (данные)
... среднее значение = сумма (данные) / n
... total_square_dev = sum ((x - среднее) ** 2 для x в данных)
... вернуть total_square_dev / (n - ddof)
...
>>> дисперсия ([3, 4, 7, 5, 6, 2, 9, 4, 1, 3])
5.24
Во второй реализации variance ()
дисперсия вычисляется в несколько этапов. Каждый шаг представлен временной переменной с понятным именем.
Временные переменные, такие как n
, означают
и total_square_dev
, часто помогают при отладке кода. Если, например, что-то пойдет не так с одним из них, вы можете вызвать print ()
, чтобы узнать, что происходит, до того, как будет запущен оператор return
.
В общем, вам следует избегать использования сложных выражений в операторе return
. Вместо этого вы можете разбить свой код на несколько шагов и использовать временные переменные для каждого шага. Использование временных переменных может упростить отладку, понимание и поддержку кода.
Возвращаемые значения и изменение глобалов
Функции, в которых нет явного return
со значимым возвращаемым значением, часто предшествуют действиям, которые имеют побочные эффекты.Побочный эффект может заключаться, например, в печати чего-либо на экране, изменении глобальной переменной, обновлении состояния объекта, записи некоторого текста в файл и т. Д.
Изменение глобальных переменных обычно считается плохой практикой программирования. Как и программы со сложными выражениями, программы, изменяющие глобальные переменные, могут быть трудными для отладки, понимания и обслуживания.
Когда вы изменяете глобальные переменные, вы потенциально влияете на все функции, классы, объекты и любые другие части ваших программ, которые полагаются на эту глобальную переменную.
Чтобы понять программу, которая изменяет глобальные переменные, вам необходимо знать все части программы, которые могут видеть, получать доступ и изменять эти переменные. Итак, хорошая практика рекомендует писать автономных функций , которые принимают некоторые аргументы и возвращают полезное значение (или значения), не вызывая каких-либо побочных эффектов для глобальных переменных.
Кроме того, функции с явным выражением return
, возвращающие значимое значение, легче тестировать, чем функции, которые изменяют или обновляют глобальные переменные.
В следующем примере показана функция, изменяющая глобальную переменную. Функция использует глобальный оператор
, который также считается плохой практикой программирования в Python:
>>>
>>> counter = 0
>>> def increment ():
... глобальный счетчик
... counter + = 1
...
>>> инкремент ()
>>> счетчик
1
В этом примере вы сначала создаете глобальную переменную counter
с начальным значением 0
.Внутри increment ()
вы используете оператор global
, чтобы сообщить функции, что вы хотите изменить глобальную переменную. Последний оператор увеличивает счетчик
на 1
.
Результат вызова increment ()
будет зависеть от начального значения счетчика
. Различные начальные значения для счетчика
будут давать разные результаты, поэтому результат функции не может контролироваться самой функцией.
Чтобы избежать такого поведения, вы можете написать автономный increment ()
, который принимает аргументы и возвращает согласованное значение, которое зависит только от входных аргументов:
>>>
>>> counter = 0
>>> def приращение (var):
... вернуть var + 1
...
>>> инкремент (счетчик)
1
>>> счетчик
0
>>> # Явно присвоить новое значение счетчику
>>> счетчик = приращение (счетчик)
>>> счетчик
1
Теперь результат вызова increment ()
зависит только от входных аргументов, а не от начального значения counter
. Это делает функцию более надежной и легкой для тестирования.
Кроме того, когда вам нужно обновить счетчик
, вы можете сделать это явно с помощью вызова increment ()
.Таким образом, у вас будет больше контроля над тем, что происходит со счетчиком
во всем вашем коде.
В целом рекомендуется избегать функций, изменяющих глобальные переменные. Если возможно, попробуйте написать автономных функций с явным оператором return
, который возвращает связное и осмысленное значение.
Использование
return
с условными операторами
Функции
Python не ограничиваются одним оператором return
.Если данная функция имеет более одного оператора return
, то первый встреченный оператор определит конец выполнения функции, а также ее возвращаемое значение.
Распространенным способом написания функций с несколькими операторами return
является использование условных операторов, которые позволяют предоставлять различные операторы return
в зависимости от результата оценки некоторых условий.
Предположим, вам нужно закодировать функцию, которая принимает число и возвращает его абсолютное значение.Если число больше 0
, вы вернете то же число. Если число меньше 0
, вы вернете его противоположное или неотрицательное значение.
Вот возможная реализация этой функции:
>>>
>>> def my_abs (число):
... если число> 0:
... вернуть номер
... число elif <0:
... return -number
...
>>> my_abs (-15)
15
>>> my_abs (15)
15
my_abs ()
имеет два явных оператора return
, каждый из которых заключен в собственный оператор if
.Он также имеет неявный оператор return
. Если номер
оказывается 0
, то ни одно из условий не является истинным, и функция завершается без попадания в какой-либо явный оператор return
. Когда это произойдет, вы автоматически получите Нет
.
Взгляните на следующий вызов my_abs ()
с использованием 0
в качестве аргумента:
>>>
>>> print (my_abs (0))
Никто
Когда вы вызываете my_abs ()
, используя в качестве аргумента 0
, в результате вы получаете None
.Это потому, что поток выполнения доходит до конца функции, не доходя до какого-либо явного оператора return
. К сожалению, абсолютное значение 0
равно 0
, а не Нет
.
Чтобы решить эту проблему, вы можете добавить третий оператор return
либо в новое предложение elif
, либо в последнее предложение else
:
>>>
>>> def my_abs (число):
... если число> 0:
... вернуть номер
... elif number <0:
... return -number
... еще:
... вернуть 0
...
>>> my_abs (0)
0
>>> my_abs (-15)
15
>>> my_abs (15)
15
Теперь my_abs ()
проверяет все возможные условия, число > 0
, число <0
и число == 0
. Цель этого примера - показать, что, когда вы используете условные операторы для предоставления нескольких операторов return
, вам необходимо убедиться, что каждая возможная опция получает свой собственный оператор return
.В противном случае в вашей функции будет скрытая ошибка.
Наконец, вы можете реализовать my_abs ()
более кратким, эффективным и питоническим способом, используя один оператор if
:
>>>
>>> def my_abs (число):
... если число <0:
... return -number
... вернуть номер
...
>>> my_abs (0)
0
>>> my_abs (-15)
15
>>> my_abs (15)
15
В этом случае ваша функция попадает в первый оператор return
, если число <0
.Во всех остальных случаях, будь то number> 0
или number == 0
, он попадает во второй оператор return
. С этой новой реализацией ваша функция выглядит намного лучше. Он более читабельный, лаконичный и эффективный.
Примечание: Существует удобная встроенная функция Python под названием abs ()
для вычисления абсолютного значения числа. Функция в приведенном выше примере предназначена только для иллюстрации обсуждаемого вопроса.
Если вы используете операторы if
для предоставления нескольких операторов return
, тогда вам не нужно условие else
для покрытия последнего условия.Просто добавьте оператор return
в конце блока кода функции и на первом уровне отступа.
Возвращается
Верно
или Ложно
Другой распространенный вариант использования комбинации , если
и возвращают операторы
, - это когда вы кодируете предикат или функцию с логическим значением. Эта функция возвращает либо True
, либо False
в соответствии с заданным условием.
Например, скажем, вам нужно написать функцию, которая принимает два целых числа, a
и b
, и возвращает True
, если a
делится на b
.В противном случае функция должна вернуть False
. Вот возможная реализация:
>>>
>>> def is_divisible (a, b):
... если не a% b:
... вернуть True
... вернуть False
...
>>> is_divisible (4, 2)
Правда
>>> is_divisible (7, 4)
Ложь
is_divisible ()
возвращает True
, если остаток от деления a
на b
равен 0
. В противном случае возвращается Ложь
.Обратите внимание, что в Python значение 0
является ложным, поэтому вам нужно использовать оператор , а не
, чтобы отрицать значение истинности условия.
Иногда вы пишете функции-предикаты, которые включают в себя такие операторы, как следующие:
В этих случаях вы можете напрямую использовать логическое выражение в операторе return
. Это возможно, потому что эти операторы возвращают либо True
, либо False
. Следуя этой идее, вот новая реализация is_divisible ()
:
.
>>>
>>> def is_divisible (a, b):
... вернуть не% b
...
>>> is_divisible (4, 2)
Правда
>>> is_divisible (7, 4)
Ложь
Если a
делится на b
, то a% b
возвращает 0
, что в Python является ложным. Итак, чтобы вернуть True
, вам нужно использовать оператор , а не
.
Примечание. Python следует набору правил для определения истинностного значения объекта.
Например, ложными считаются следующие объекты:
- Константы, такие как
Нет
иЛожь
- Числовые типы с нулевым значением, например
0
,0.0
,0j
,Десятичное (0)
иДробь (0, 1)
- Пустые последовательности и коллекции, например
""
,()
,[]
,{}
,set ()
иrange (0)
- Объекты, реализующие
__bool __ ()
с возвращаемым значениемFalse
или__len __ ()
с возвращаемым значением0
Любой другой объект будет считаться правдивым.
С другой стороны, если вы попытаетесь использовать условия, которые включают логические операторы, такие как или
, и
, как вы видели раньше, тогда ваши функции предиката не будут работать правильно.Это потому, что эти операторы ведут себя по-разному. Они возвращают один из операндов в условии, а не True
или False
:
>>>
>>> 0 и 1
0
>>> 1 и 2
2
>>> 1 или 2
1
>>> 0 или 1
1
Обычно и
возвращают первый ложный операнд или последний операнд. С другой стороны, или
возвращает первый истинный операнд или последний операнд. Итак, чтобы написать предикат, включающий один из этих операторов, вам нужно будет использовать явный оператор if
или вызов встроенной функции bool ()
.
Предположим, вы хотите написать функцию предиката, которая принимает два значения и возвращает Истина,
, если оба верны, и Ложь,
в противном случае. Вот ваш первый подход к этой функции:
>>>
>>> def both_true (a, b):
... вернуть a и b
...
>>> both_true (1, 2)
2
Поскольку и
возвращают операнды вместо True
или False
, ваша функция работает некорректно. Есть как минимум три возможности решить эту проблему:
- Явный оператор
if
- Условное выражение (тернарный оператор)
- Встроенная функция Python
bool ()
Если вы используете первый подход, то вы можете записать both_true ()
следующим образом:
>>>
>>> def both_true (a, b):
... если a и b:
... вернуть True
... вернуть False
...
>>> both_true (1, 2)
Правда
>>> both_true (1, 0)
Ложь
Оператор if
проверяет, являются ли оба a
и b
правдой. Если это так, то both_true ()
возвращает True
. В противном случае возвращается Ложь
.
Если, с другой стороны, вы используете условное выражение Python или тернарный оператор, то вы можете написать свою функцию-предикат следующим образом:
>>>
>>> def both_true (a, b):
... вернуть True, если a и b иначе False
...
>>> both_true (1, 2)
Правда
>>> both_true (1, 0)
Ложь
Здесь вы используете условное выражение для предоставления возвращаемого значения для both_true ()
. Условное выражение оценивается как True
, если оба значения a
и b
истинны. В противном случае окончательный результат: Ложь
.
Наконец, если вы используете bool ()
, вы можете закодировать both_true ()
следующим образом:
>>>
>>> def both_true (a, b):
... вернуть bool (a и b)
...
>>> both_true (1, 2)
Правда
>>> both_true (1, 0)
Ложь
bool ()
возвращает True
, если a
и b
истинны, и False
в противном случае. Вам решать, какой подход использовать для решения этой проблемы. Однако второе решение кажется более читаемым. Как вы думаете?
Короткозамыкающие петли
Оператор return
внутри цикла выполняет какое-то короткое замыкание .Это прерывает выполнение цикла и немедленно возвращает функцию. Чтобы лучше понять это поведение, вы можете написать функцию, которая имитирует any ()
. Эта встроенная функция принимает итерацию и возвращает True
, если хотя бы один из ее элементов является истинным.
Чтобы эмулировать any ()
, вы можете закодировать функцию, подобную следующей:
>>>
>>> def my_any (повторяемый):
... для элемента в итерации:
... если элемент:
... # Короткое замыкание
... вернуть True
... вернуть False
>>> my_any ([0, 0, 1, 0, 0])
Правда
>>> my_any ([0, 0, 0, 0, 0])
Ложь
Если любой элемент
в итерабельном
истинен, то поток выполнения входит в блок if
. Оператор return
прерывает цикл и немедленно возвращает значение True
. Если в итерабельном
нет значения, то my_any ()
возвращает False
.
Эта функция реализует оценку короткого замыкания . Например, предположим, что вы передаете итерацию, содержащую миллион элементов. Если первый элемент в этой итерации оказывается истинным, то цикл выполняется только один раз, а не миллион раз. Это может сэкономить вам много времени на обработку при запуске вашего кода.
Важно отметить, что для использования оператора return
внутри цикла необходимо заключить его в оператор if
.В противном случае цикл всегда прерывается на первой итерации.
Распознавание мертвого кода
Как только функция встречает оператор return
, она завершается без выполнения какого-либо последующего кода. Следовательно, код, который появляется после оператора return
функции, обычно называется мертвым кодом . Интерпретатор Python полностью игнорирует мертвый код при запуске ваших функций. Таким образом, использование такого кода в функции бесполезно и сбивает с толку.
Рассмотрим следующую функцию, которая добавляет код после своего оператора return
:
>>>
>>> def dead_code ():
... возврат 42
... # Мертвый код
... print ("Привет, мир")
...
>>> dead_code ()
42
Оператор print ("Hello, World")
в этом примере никогда не будет выполняться, потому что этот оператор появляется после оператора return
функции. Выявление мертвого кода и его удаление - хорошая практика, которую вы можете применить для написания лучших функций.
Стоит отметить, что если вы используете условные операторы для предоставления нескольких операторов return
, тогда у вас может быть код после оператора return
, который не будет мертвым, пока он находится за пределами оператора if
:
>>>
>>> def no_dead_code (условие):
... если условие:
... возврат 42
... print ("Привет, мир")
...
>>> no_dead_code (Истина)
42
>>> no_dead_code (Ложь)
Привет мир
Даже несмотря на то, что вызов print ()
происходит после оператора return
, это не мертвый код.Когда условие
оценивается как False
, запускается вызов print ()
, и на ваш экран выводится Hello, World
.
Возврат нескольких именованных объектов
Когда вы пишете функцию, которая возвращает несколько значений в одном операторе return
, вы можете рассмотреть возможность использования объекта collections. namedtuple
, чтобы сделать ваши функции более удобочитаемыми. namedtuple
- это класс коллекции, который возвращает подкласс кортежа
, который имеет поля или атрибуты.Вы можете получить доступ к этим атрибутам, используя точечную нотацию или операцию индексации.
Инициализатор namedtuple
принимает несколько аргументов. Однако, чтобы начать использовать namedtuple
в своем коде, вам просто нужно знать о первых двух:
-
typename
содержит имя кортежного класса, который вы создаете. Это должна быть строка. -
field_names
содержит имена полей или атрибутов кортежного класса.Это может быть последовательность строк, например["x", "y"]
, или одна строка, каждое имя которой разделено пробелами или запятыми, например"x y"
или"x, y"
.
Использование именованного кортежа
, когда вам нужно вернуть несколько значений, может сделать ваши функции значительно более удобочитаемыми без особых усилий. Рассмотрим следующее обновление describe ()
с использованием namedtuple
в качестве возвращаемого значения:
статистика импорта как st
из коллекции импортировать namedtuple
def описать (образец):
Desc = namedtuple ("Desc", ["средний", "средний", "режим"])
return Desc (
ул.среднее (образец),
st.median (образец),
st.mode (образец),
)
Внутри describe ()
вы создаете именованный кортеж
с именем Desc
. Этот объект может иметь именованные атрибуты, к которым вы можете получить доступ, используя точечную нотацию или операцию индексирования. В этом примере этими атрибутами являются «среднее значение»
, «среднее значение»
и «режим»
.
Вы можете создать объект Desc
и использовать его в качестве возвращаемого значения.Для этого вам нужно создать экземпляр Desc
, как если бы вы делали это с любым классом Python. Обратите внимание, что вам необходимо указать конкретное значение для каждого именованного атрибута, как вы это делали в операторе return
.
Вот как теперь работает describe ()
:
>>>
>>> sample = [10, 2, 4, 7, 9, 3, 9, 8, 6, 7]
>>> stat_desc = описать (образец)
>>> stat_desc
Desc (среднее значение = 5,7, медиана = 6,0, режим = 6)
>>> # Получить среднее значение по имени его атрибута
>>> stat_desc.иметь в виду
5,7
>>> # Получение медианы по ее индексу
>>> stat_desc [1]
6.0
>>> # Распаковать значения в три переменные
>>> среднее, медиана, режим = описать (образец)
>>> означает
5,7
>>> режим
6
Когда вы вызываете describe ()
с выборкой числовых данных, вы получаете объект namedtuple
, содержащий среднее, медианное значение и режим выборки. Обратите внимание, что вы можете получить доступ к каждому элементу кортежа, используя либо точечную нотацию, либо операцию индексации.
Наконец, вы также можете использовать итеративную операцию распаковки, чтобы сохранить каждое значение в отдельной независимой переменной.
Функции возврата: закрытие
В Python функции - это объекты первого класса. Первоклассный объект - это объект, который может быть назначен переменной, передан в качестве аргумента функции или использован в качестве возвращаемого значения в функции. Таким образом, вы можете использовать объект функции в качестве возвращаемого значения в любом операторе return
.
Функция, которая принимает функцию в качестве аргумента, возвращает функцию в качестве результата или и то, и другое является функцией высшего порядка.Фабрика закрытия - это типичный пример функции высшего порядка в Python. Эта функция принимает некоторые аргументы и возвращает внутреннюю функцию. Внутренняя функция обычно известна как закрытие .
Замыкание несет информацию о охватывающем его объеме выполнения. Это дает возможность сохранять информацию о состоянии между вызовами функций. Функции фабрики закрытия полезны, когда вам нужно написать код, основанный на концепции ленивого или отложенного вычисления.
Предположим, вам нужно написать вспомогательную функцию, которая принимает число и возвращает результат умножения этого числа на заданный коэффициент.Вы можете закодировать эту функцию следующим образом:
def by_factor (коэффициент, число):
коэффициент возврата * число
by_factor ()
принимает фактор
и число
в качестве аргументов и возвращает их результат. Поскольку коэффициент
редко меняется в вашем приложении, вам неприятно указывать один и тот же коэффициент при каждом вызове функции. Итак, вам нужен способ сохранить состояние или значение , коэффициент
между вызовами by_factor ()
и изменять его только при необходимости.Чтобы сохранить текущее значение , коэффициент
между вызовами, вы можете использовать закрытие.
Следующая реализация by_factor ()
использует замыкание для сохранения значения , фактор
между вызовами:
>>>
>>> def by_factor (коэффициент):
... def умножить (число):
... коэффициент возврата * число
... вернуть умножить
...
>>> двойной = по_фактору (2)
>>> двойной (3)
6
>>> двойной (4)
8
>>> тройной = по_фактору (3)
>>> тройной (3)
9
>>> тройной (4)
12
Внутри by_factor ()
вы определяете внутреннюю функцию с именем multiply ()
и возвращаете ее, не вызывая ее.Возвращаемый вами функциональный объект - это замыкание, которое сохраняет информацию о состоянии , фактор
. Другими словами, он запоминает значение , коэффициент
между вызовами. Вот почему double
запоминает, что коэффициент
был равен 2
, а triple
запоминает, что коэффициент
был равен 3
.
Обратите внимание, что вы можете свободно повторно использовать double
и triple
, потому что они не забывают информацию о своем состоянии.
Для создания замыканий можно также использовать лямбда-функцию
. Иногда использование функции лямбда
может сделать вашу фабрику укупорочных средств более лаконичной. Вот альтернативная реализация by_factor ()
с использованием лямбда-функции
:
>>>
>>> def by_factor (коэффициент):
... вернуть лямбда-число: коэффициент * число
...
>>> двойной = по_фактору (2)
>>> двойной (3)
6
>>> двойной (4)
8
Эта реализация работает так же, как и в исходном примере.В этом случае использование лямбда-функции
обеспечивает быстрый и лаконичный способ кодирования by_factor ()
.
Функции приема и возврата: декораторы
Другой способ использования оператора return
для возврата объектов-функций - это написать функции-декораторы. Функция декоратора принимает объект функции в качестве аргумента и возвращает объект функции. Декоратор каким-то образом обрабатывает декорированную функцию и возвращает ее или заменяет другой функцией или вызываемым объектом.
Декораторы полезны, когда вам нужно добавить дополнительную логику к существующим функциям, не изменяя их. Например, вы можете закодировать декоратор для регистрации вызовов функций, проверки аргументов функции, измерения времени выполнения данной функции и т. Д.
В следующем примере показана функция-декоратор, которую можно использовать, чтобы получить представление о времени выполнения данной функции Python:
>>>
>>> импортное время
>>> def my_timer (func):
... def _timer (* args, ** kwargs):
... start = time.time ()
... результат = func (* args, ** kwargs)
... конец = time.time ()
... print (f "Время выполнения: {end - start}")
... вернуть результат
... вернуть _timer
...
>>> @my_timer
... def delayed_mean (образец):
... время. сон (1)
... вернуть сумму (образец) / len (образец)
...
>>> delayed_mean ([10, 2, 4, 7, 9, 3, 9, 8, 6, 7])
Время исполнения: 1.0011096000671387
6.5
Синтаксис @my_timer
над заголовком delayed_mean ()
эквивалентен выражению delayed_mean = my_timer (delayed_mean)
.В этом случае можно сказать, что my_timer ()
украшает delayed_mean ()
.
Python запускает функции декоратора, как только вы импортируете или запускаете модуль или скрипт. Итак, когда вы вызываете delayed_mean ()
, вы действительно вызываете возвращаемое значение my_timer ()
, которое является объектом функции _timer
. Вызов декорированного delayed_mean ()
вернет среднее значение выборки, а также будет измерять время выполнения исходного delayed_mean ()
.
В этом случае вы используете time ()
для измерения времени выполнения внутри декоратора. time ()
находится в модуле time
, который предоставляет набор функций, связанных со временем. time ()
возвращает время в секундах с начала эпохи в виде числа с плавающей запятой. Разница между временем до и после вызова delayed_mean ()
даст вам представление о времени выполнения функции.
Другими распространенными примерами декораторов в Python являются classmethod ()
, staticmethod ()
и property ()
.Если вы хотите глубже погрузиться в декораторы Python, взгляните на Primer on Python Decorators. Вы также можете проверить Python Decorators 101.
Возврат определяемых пользователем объектов: заводской шаблон
Оператор Python return
также может возвращать определенные пользователем объекты. Другими словами, вы можете использовать свои собственные настраиваемые объекты в качестве возвращаемого значения в функции. Типичным вариантом использования этой возможности является фабричный шаблон.
Заводской шаблон определяет интерфейс для создания объектов "на лету" в ответ на условия, которые вы не можете предсказать, когда пишете программу.Вы можете реализовать фабрику определяемых пользователем объектов, используя функцию, которая принимает некоторые аргументы инициализации и возвращает различные объекты в соответствии с конкретным вводом.
Допустим, вы пишете приложение для рисования. Вам нужно на лету создавать различные формы в зависимости от выбора пользователя. В вашей программе будут квадраты, круги, прямоугольники и так далее. Чтобы создавать эти формы на лету, вам сначала нужно создать классы фигур, которые вы собираетесь использовать:
класс Круг:
def __init __ (self, radius):
себя.radius = радиус
# Реализация класса ...
класс Square:
def __init __ (я, сторона):
self.side = сторона
# Реализация класса ...
Если у вас есть класс для каждой формы, вы можете написать функцию, которая принимает имя формы в виде строки и необязательный список аргументов ( * args
) и аргументов ключевого слова ( ** kwargs
) для создания и инициализировать формы на лету:
def shape_factory (shape_name, * args, ** kwargs):
shape = {"circle": круг, "square": квадрат}
вернуть формы [shape_name] (* args, ** kwargs)
Эта функция создает экземпляр конкретной формы и возвращает его вызывающей стороне.Теперь вы можете использовать shape_factory ()
для создания объектов различной формы в соответствии с потребностями ваших пользователей:
>>>
>>> circle = shape_factory ("круг", радиус = 20)
>>> тип (круг)
<класс '__main __. Circle'>
>>> circle.radius
20
>>> square = shape_factory ("квадрат", сторона = 10)
>>> тип (квадрат)
<класс '__main __. Square'>
>>> square.side
10
Если вы вызовете shape_factory ()
с именем требуемой формы в виде строки, вы получите новый экземпляр формы, который соответствует shape_name
, который вы только что передали на фабрику.
Использование
возврат
в попытка
… наконец
Блоки
Когда вы используете оператор return
внутри оператора try
с предложением finally
, это предложение finally
всегда выполняется перед оператором return
. Это гарантирует, что код в предложении finally
всегда будет выполняться. Посмотрите на следующий пример:
>>>
>>> def func (значение):
... пытаться:
... вернуть float (значение)
... кроме ValueError:
... вернуть str (значение)
... наконец-то:
... print ("Запустите это перед возвратом")
...
>>> func (9)
Запустите это перед возвращением
9.0
>>> func ("один")
Запустите это перед возвращением
'один'
Когда вы вызываете func ()
, вы получаете значение
, преобразованное в число с плавающей запятой или строковый объект. Перед этим ваша функция запускает предложение finally
и выводит сообщение на ваш экран.Какой бы код вы ни добавили в предложение finally
, он будет выполнен до того, как функция выполнит свой оператор return
.
Использование
return
в функциях генератора
Функция Python с оператором yield
в теле является функцией генератора . Когда вы вызываете функцию генератора, она возвращает итератор генератора. Итак, можно сказать, что функция генератора - это генератор фабрики .
Вы можете использовать оператор return
внутри функции генератора, чтобы указать, что генератор готов.Оператор return
заставит генератор поднять StopIteration
. Возвращаемое значение будет передано в качестве аргумента инициализатору StopIteration
и будет присвоено его атрибуту .value
.
Вот генератор, который по запросу возвращает 1
и 2
, а затем возвращает 3
:
.
>>>
>>> def gen ():
... выход 1
... yield 2
... вернуть 3
...
>>> g = gen ()
>>> г
<генератор объекта в 0x7f4ff4853c10>
>>> следующий (g)
1
>>> следующий (g)
2
>>> следующий (g)
Отслеживание (последний вызов последний):
Файл "", строка 1, в
следующий (г)
StopIteration: 3
gen ()
возвращает объект-генератор, который по запросу дает 1
и 2
.Чтобы получить каждое число из объекта-генератора, вы можете использовать next ()
, которая является встроенной функцией, которая извлекает следующий элемент из генератора Python.
Первые два вызова next ()
возвращают 1
и 2
соответственно. В третьем вызове генератор истощен, и вы получаете StopIteration
. Обратите внимание, что возвращаемое значение функции генератора ( 3
) становится атрибутом .value
объекта StopIteration
.
Заключение
Оператор Python return
позволяет вам отправить любой объект Python из ваших пользовательских функций обратно в вызывающий код. Этот оператор является фундаментальной частью любой функции или метода Python. Если вы научитесь его использовать, то будете готовы кодировать надежные функции.
Из этого руководства вы узнали, как:
- Эффективно используйте оператор Python
return
в ваших функциях - Вернуть одиночных или множественных значений из ваших функций в код вызывающего абонента
- Примените передовой опыт при использовании отчета о возврате
Кроме того, вы узнали о некоторых более сложных случаях использования оператора return
, например, как кодировать функцию фабрики замыкания и функцию декоратора.Обладая этими знаниями, вы сможете писать на Python больше питонических, надежных и поддерживаемых функций.
Оператор возврата Python - GeeksforGeeks
Оператор возврата Python
Оператор return
используется для завершения выполнения вызова функции и «возвращает» результат (значение выражения, следующее за ключевым словом return
) вызывающей стороне. Операторы после операторов возврата не выполняются. Если оператор return не содержит никакого выражения, возвращается специальное значение None
.
Примечание: Оператор возврата не может использоваться вне функции.
Синтаксис:
def fun (): заявления . . return [выражение]
Пример:
|
Выход:
Результат добавления функции 5 Результат функции is_true - True
Возвращение нескольких значений
В Python мы можем возвращать несколько значений из функции.Ниже приведены разные способы.
Функция, возвращающая другую функцию
В Python функции являются объектами, поэтому мы можем вернуть функцию из другой функции. Это возможно, потому что функции рассматриваются в Python как объекты первого класса. Чтобы узнать больше о первоклассных объектах, нажмите здесь.
В приведенном ниже примере функция create_adder
возвращает функцию adder
.
|
Выход:
Результат 25 Результат: 100
Внимание компьютерщик! Укрепите свои основы с помощью курса Python Programming Foundation и изучите основы.
Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS . И чтобы начать свое путешествие по машинному обучению, присоединяйтесь к Машинное обучение - курс базового уровня
Как использовать оператор возврата в Python
Если вы хотите, чтобы функции работали, как ожидалось, то в каждом из них должен быть оператор возврата. язык программирования. Ключевое слово return предназначено для выхода из функции и возврата значения.
Python return
Python return - это встроенный оператор или ключевое слово, которое используется для завершения выполнения вызова функции, и « возвращает » результат (значение выражения, следующего за ключевым словом return) вызывающей стороне .
Оператор после оператора возврата не выполняется. Если оператор return не содержит выражения, возвращается None.
Обратите внимание на одну вещь: оператор return в Python не может использоваться вне функции.
Синтаксис
def method (): заявления . . return [выражение]
Пример
def club (): возврат 11 + 19 печать (клуб ())
Выходные данные
30
В этом примере мы определили функцию, которая возвращает сумму двух значений.В этом примере возвращается одно значение.
Python возвращает несколько значений.
Чтобы вернуть несколько значений в Python из функции, мы можем использовать следующие способы.
- Возврат нескольких значений через запятую (кортеж)
- Список возврата
- Набор возврата
- Словарь возврата
Возврат нескольких значений через запятую
Чтобы вернуть несколько значений через запятую, используйте оператор return. В Python вы можете просто вернуть несколько значений, разделенных запятыми.Возвращаемые значения представляют собой кортеж Python со значениями, разделенными запятыми.
def клуб (): возврат 11, 19, 21, 46 печать (клуб ())
Выходные данные
(11, 19, 21, 46)
Из выходных данных видно, что функция вернула кортеж, содержащий значения, разделенные командами.
В Python значения, разделенные запятыми, считаются кортежами без скобок, за исключением случаев, когда этого требует синтаксис.
Мы также можем проверить его тип данных.
def клуб (): возврат 11, 19, 21, 46 печать (тип (клуб ()))
Вывод
Вы можете получить доступ к элементу по его индексу.
def клуб (): возврат 11, 19, 21, 46 данные = клуб () печать (данные [2])
Выходные данные
21
Если вы попытаетесь получить доступ к несуществующему индексу, он выдаст исключение.
def клуб (): возврат 11, 19, 21, 46 данные = клуб () печать (данные [20])
Выход
Отслеживание (последний вызов последним): Файл "app.py", строка 5, впечать (данные [20]) IndexError: индекс кортежа вне диапазона
Мы получили IndexError: индекс кортежа вне диапазона.
Возврат списка в Python
Чтобы вернуть список в Python, используйте ключевое слово return, а затем напишите список, который вы хотите вернуть, внутри функции. Список Python похож на массив элементов, созданных с использованием квадратных скобок.
Списки отличаются от массивов тем, что могут содержать элементы разных типов. Списки в Python отличаются от кортежей, поскольку они изменяемы.
def клуб (): str = "AppDividend" х = 20 return [str, x] данные = клуб () печать (данные)
Выходные данные
['AppDividend', 20]
В этом коде мы видим, что у нас есть список возврата с помощью [].
Использование [] возвращает список вместо кортежа.
Возврат словаря
Чтобы вернуть словарь в Python, используйте ключевое слово return, а затем напишите словарь, который вы хотите вернуть, внутри функции. Словарь Python похож на хэш или карту на других языках.
Мы можем определить словарь, используя метод dict (), а затем указать ключ в соответствии со значениями, и мы составим словарь и вернем словарь.
def клуб (): dct = dict () dct ['str'] = "AppDividend" dct ['age'] = 3 вернуть dct данные = клуб () печать (данные)
Выходные данные
{'str': 'AppDividend', 'age': 3}
Вы можете видеть, что мы сначала инициализировали пустой словарь, а затем добавили пары ключ-значение в словарь.А потом верните словарь.
Наконец, пример оператора возврата Python завершен.
Что это такое и почему вы их используете
Все функции возвращают значение при вызове.
Если за оператором return следует список выражений, этот список выражений оценивается и возвращается значение:
>>> def better_than_1 (n):
... вернуть n> 1
...
>>> печать (больше_тан_1 (1))
Ложь
>>> печать (больше_тан_1 (2))
Истина
Если список выражений не указан, возвращается Нет
:
>>> def no_expression_list ():
... return # Нет списка возвращаемых выражений.
...
>>> print (список_выражений ())
Нет
Если оператор return достигается во время выполнения функции, текущий вызов функции остается в этой точке:
>>> def return_middle ():
... а = 1
... вернуть
... a = 2 # Это назначение никогда не достигается.
...
>>> печать (return_middle ())
1
Если оператора return нет, функция возвращает None по достижении конца:
>>> def no_return ():
... pass # Нет оператора возврата.
...
>>> печать (no_return ())
Никто
Одна функция может иметь несколько операторов return
. Выполнение функции заканчивается, когда достигается один из этих return
операторов:
>>> def multiple_returns (n):
... если (n):
... return "Первое заявление о возврате"
... еще:
... return "Второе заявление о возврате"
...
>>> print (multiple_returns (Истина))
Заявление о первом возврате
>>> print (multiple_returns (Ложь))
Второе заявление о возврате
Одна функция может возвращать различные типы:
>>> def different_return_types (n):
... если (n == 1):
... верните "Hello World". # Вернуть строку
... elif (n == 2):
... return 42 # Вернуть значение
... еще:
... return True # Вернуть логическое значение
...
>>> печать (различные_возвратные_типы (1))
Привет мир.
>>> печать (различные_возвратные_типы (2))
42
>>> печать (различные_возвратные_типы (3))
True
Возможно даже, чтобы одна функция возвращала несколько значений только с одним возвратом:
>>> def return_two_values ():
... а = 40
... Ь = 2
... вернуть a, b
...
>>> print ("Первое значение =% d, Второе значение =% d"% (return_two_values ()))
Первое значение = 40, Второе значение = 2
Дополнительную информацию см. В документации Python.
Python Return: пошаговое руководство
Оператор возврата Python указывает Python продолжить выполнение основной программы. Вы можете использовать оператор return для отправки значения обратно в основную программу, например строки или списка.
Функции - это блоки инструкций, которые выполняют определенную задачу программирования.После объявления функции ее можно использовать многократно. Основное преимущество использования функций заключается в том, что они позволяют сократить количество строк кода, которые вы пишете.
При работе с функциями в Python вы встретите оператор return . Этот оператор останавливает выполнение функции и возвращает значения из функции в основную программу.
В этом руководстве мы собираемся обсудить, как работает оператор return и как использовать return для отправки значений в основную программу.
Обновление функций Python
Python включает ряд встроенных функций, таких как print () , str () и len () , которые выполняют определенные задачи.
Вы можете объявить свою собственную функцию Python с помощью ключевого слова def . После использования ключевого слова def вы должны указать имя вашей функции. Затем вы должны указать в круглых скобках. Скобки могут содержать любые параметры, которые должна принимать ваша функция.
Вот синтаксис объявления функции в Python:
def example_function (): ваш код здесь
Возврат Python
Ключевое слово return Python завершает функцию и указывает Python продолжить выполнение основной программы. Ключевое слово return может отправить значение обратно в основную программу. Значение может быть строкой, кортежем или любым другим объектом.
Это полезно, потому что позволяет обрабатывать данные внутри функции. Затем мы можем вернуть данные в нашу основную программу, чтобы использовать их вне нашей функции.
Данные, обрабатываемые внутри функции, доступны только внутри функции. Это только тот случай, если вы не используете оператор return для отправки данных в другое место в программе.
Вот синтаксис ключевого слова return:
def example_function (): return "Пример"
Ключевое слово return может появляться в любом месте функции, и когда код выполняет оператор return, функция будет завершена.
Оператор return возвращает значение остальной части программы, но его также можно использовать отдельно.Если после оператора return выражение не определено, возвращается None . Вот пример этого в действии:
def example_function (): возвращаться example_function ()
Наш код возвращает: Нет .
Вы можете решить не указывать значение, если хотите, чтобы функция прекращала выполнение только после определенного момента. Это менее распространенный вариант использования оператора return Python.
Возврат Python: пример
Допустим, у нас работает ресторан.Мы хотим создать программу, которая возвращает стоимость сэндвич-блюд, которые есть в меню. Эта задача должна содержаться в функции, потому что мы собираемся использовать ее более одного раза.
Официантка должна ввести название сэндвича, который заказал клиент, и получить цену сэндвича. Мы могли бы выполнить эту задачу, используя следующий код:
sandwich = "Ветчина и сыр" def calculate_price (продукт): if product == "Ветчина и сыр": возврат 2.50 elif product == "Тунец и огурец": доход 2.25 elif product == "Яйцо Майонез": доход 2.25 elif product == "Куриный клуб": возврат 2.75 еще: возврат 2.50 Calcul_price (бутерброд)
Давайте запустим нашу программу и посмотрим, что произойдет:
В первой строке кода мы объявляем название бутерброда, цену которого мы хотим узнать. В этом случае наша переменная Python sandwich хранит значение Ham and Cheese .
Затем мы объявляем функцию с именем calculate_price () , которая принимает один параметр: название бутерброда, который клиент хотел бы купить.Мы использовали операторы Python if, чтобы сравнить название продукта с нашим списком бутербродов. Когда название продукта найдено, наша программа возвращает цену, которую она определила.
Вот возможные значения с плавающей запятой Python, которые может вернуть наша программа:
- «Ветчина и сыр»: 2,50
- «Куриный клуб»: 2,75
- Другой сэндвич: 2,50
В последней строке мы вызываем наш метод calculate_price () и передаем переменную сэндвича в качестве аргумента.Когда вызывается наш метод calculate_price () , наша программа выполняет этот метод и возвращает цену указанного сэндвича.
В данном случае наш клиент заказал бутерброд Ветчина и сыр , поэтому наша программа возвращает 2.50.
Как только будет выполнен оператор return , наша функция остановится, а наша программа продолжит выполнение.
Возврат в Python: еще один пример
Давайте воспользуемся другим примером оператора return , чтобы проиллюстрировать его работу.Допустим, мы создаем программу, которая рассчитывает изменение, которое клиент должен получить. Мы могли бы выполнить эту задачу, используя следующий код:
цена = 2.50 def calculate_change (сумма_дано): return amount_given - цена Calcul_change (4.00)
Наш код возвращает:
Мы объявили функцию под названием calculate_change , которая вычитает цену сэндвича из суммы, указанной клиентом. В этом случае цена бутерброда составляет 2 доллара.50, а пользователь дал официантке 4 доллара. Итак, наша программа возвращает 1,50 доллара.
Заключение
Ключевое слово return в Python завершает функцию и сообщает Python, что нужно запустить остальную часть основной программы. Ключевое слово return может отправить значение обратно в основную программу.
Хотя значения могут быть определены в функции, вы можете отправить их обратно в свою основную программу и прочитать их во всем коде.
В этом руководстве мы углубились в основы оператора return Python.Мы также рассмотрели два примера функций Python, которые использовали ключевое слово return, чтобы проиллюстрировать, как работает оператор.
Чтобы найти курсы, учебные ресурсы и дополнительную информацию о Python, ознакомьтесь с нашим полным руководством «Как выучить Python».
7. Простые операторы - документация Python 3.9.5
Простая инструкция состоит из одной логической строки. Несколько простых
операторы могут находиться в одной строке, разделенной точкой с запятой. Синтаксис для
простые инструкции:
simple_stmt :: =expression_stmt
|assert_stmt
|assignment_stmt
|augmented_assignment_stmt
|annotated_assignment_stmt
|pass_stmt
|del_stmt
|return_stmt
|yield_stmt
|raise_stmt
|break_stmt
|continue_stmt
|import_stmt
|future_stmt
|global_stmt
|nonlocal_stmt
7.1. Выражения
Операторы выражений используются (в основном в интерактивном режиме) для вычисления и записи
значение или (обычно) для вызова процедуры (функции, которая не возвращает значимого
результат; в Python процедуры возвращают значение Нет
). Другое использование
операторы выражения разрешены и иногда полезны. Синтаксис для
выражение:
выражение_стмт :: = звездное_выражение
Оператор выражения оценивает список выражений (который может быть
выражение).
В интерактивном режиме, если значение не Нет
, оно преобразуется в строку
используя встроенную функцию repr ()
, и результирующая строка записывается в
стандартный вывод в отдельной строке (кроме случая Нет
, так что
вызовы процедур не вызывают никакого вывода.)
7.2. Заявления о присвоении
Операторы присваивания используются для (пере) привязки имен к значениям и для изменения
атрибуты или элементы изменяемых объектов:
assignment_stmt :: = (target_list
"=") + (starred_expression
|yield_expression
) target_list :: =target
(","target
) * [","] цель :: =идентификатор
| "(" [target_list
] ")" | "[" [target_list
] "]" |attributeref
|подписка
|нарезка
| «*»цель
(См. Определение синтаксиса для attributeref в разделе Primary,
подписка и нарезка .)
Оператор присваивания оценивает список выражений (помните, что это может быть
одно выражение или список, разделенный запятыми, последний дает кортеж) и
назначает единственный результирующий объект каждому из целевых списков слева направо
верно.
Присвоение определяется рекурсивно в зависимости от формы цели (списка).
Когда цель является частью изменяемого объекта (ссылка на атрибут, подписка
или нарезка), изменяемый объект должен в конечном итоге выполнить присваивание и
принять решение о его действительности и может вызвать исключение, если присвоение
неприемлемый.Правила, соблюдаемые различными типами, и исключения:
дается вместе с определением типов объектов (см. раздел Стандартная иерархия типов).
Назначение объекта целевому списку, необязательно заключенное в круглые скобки или
квадратных скобок, рекурсивно определяется следующим образом.
Если целевой список представляет собой единственную цель без конечной запятой,
необязательно в круглых скобках объект назначается этой цели.Иначе: объект должен быть итерируемым с тем же количеством
элементы, поскольку в целевом списке есть цели, и элементы назначены,
слева направо к соответствующим целям.Если целевой список содержит одну цель со звездочкой, называется
«Помеченная» цель: объект должен быть итеративным с как минимум таким же количеством элементов.
поскольку в целевом списке есть цели, минус один. Первые позиции
iterable назначаются слева направо целям перед отмеченными звездочкой
цель. Последние элементы итерации назначаются целям после
помеченная звездочкой цель. Список оставшихся в итерируемом элементе затем
назначен цели, отмеченной звездочкой (список может быть пустым).Иначе: объект должен быть итерируемым с тем же количеством элементов, что и в нем.
являются целями в целевом списке, и элементы назначаются слева направо
правильно, к соответствующим целям.
Присвоение объекта единственной цели рекурсивно определяется следующим образом.
Если целью является идентификатор (имя):
Если имя не встречается в глобальном
в текущем блоке кода: имя привязано к объекту в
текущее локальное пространство имен.В противном случае: имя привязано к объекту в глобальном пространстве имен или
внешнее пространство имен определяетсянелокальным
соответственно.
Имя является рикошетом, если оно уже было связано. Это может привести к тому, что ссылка
счетчик для объекта, ранее привязанного к имени, чтобы достичь нуля, в результате чего
объект, который нужно освободить, и его деструктор (если он есть) для вызова.Если целью является ссылка на атрибут: основное выражение в
ссылка оценивается.В результате должен получиться объект с назначаемыми атрибутами;
если это не так, возникает ошибкаTypeError
. Тогда этот объект
попросили присвоить присвоенный объект данному атрибуту; если не может
выполнить задание, возникает исключение (обычно, но не обязательно
Ошибка атрибута
).Примечание. Если объект является экземпляром класса и ссылка на атрибут встречается на
обе стороны оператора присваивания, выражение в правой части,a.x
может получить доступ
либо атрибут экземпляра, либо (если атрибут экземпляра не существует) класс
атрибут.Левая цельa.x
всегда устанавливается как атрибут экземпляра,
создавая его при необходимости. Таким образом, два появленияa.x
не
обязательно ссылаются на один и тот же атрибут: если выражение в правой части относится к
class, левая сторона создает новый атрибут экземпляра как цель
присвоение:класс Cls: x = 3 # переменная класса inst = Cls () inst.x = inst.x + 1 # записывает inst.x как 4, оставляя Cls.x как 3
Это описание не обязательно применимо к атрибутам дескриптора, таким как
свойства, созданные с помощьюproperty ()
.Если целью является подписка: основным выражением в ссылке является
оценен. Он должен давать либо изменяемый объект последовательности (например, список)
или объект отображения (например, словарь). Затем нижний индекс выражается так:
оценен.Если первичным является изменяемый объект последовательности (например, список), нижний индекс
должен давать целое число. Если он отрицательный, длина последовательности добавляется к
Это. Результирующее значение должно быть неотрицательным целым числом меньше, чем
длина последовательности, и последовательность просят назначить назначенный объект
его элемент с этим индексом.Если индекс вне допустимого диапазона,IndexError
будет
поднят (присвоение последовательности с индексами не может добавлять новые элементы в список).Если первичным является объект отображения (например, словарь), нижний индекс должен
иметь тип, совместимый с типом ключа сопоставления, и тогда сопоставление
попросили создать пару ключ / данные, которая отображает индекс в назначенный
объект. Это может заменить существующую пару ключ / значение тем же ключом.
значение или вставьте новую пару ключ / значение (если не существует ключа с таким же значением).Для пользовательских объектов метод
__setitem __ ()
вызывается с
соответствующие аргументы.Если целью является срез: основным выражением в ссылке является
оценен. Он должен дать изменяемый объект последовательности (например, список). В
назначенный объект должен быть объектом последовательности того же типа. Далее нижний
и выражения верхней границы оцениваются, если они присутствуют; значения по умолчанию
равны нулю, а длина последовательности. Границы должны быть целыми числами.Если какая-либо граница отрицательная, к ней добавляется длина последовательности. В
результирующие границы обрезаются, чтобы они находились между нулем и длиной последовательности,
включительно. Наконец, объекту последовательности предлагается заменить срез на
элементы заданной последовательности. Длина среза может быть разной.
от длины назначенной последовательности, тем самым изменяя длину
целевая последовательность, если это позволяет целевая последовательность.
Детали реализации CPython: В текущей реализации синтаксис для целей считается таким же
что касается выражений, а недопустимый синтаксис отклоняется во время генерации кода
фазы, вызывая менее подробные сообщения об ошибках.
Хотя определение присвоения подразумевает, что
левая и правая части являются «одновременными» (например, a, b =
меняет местами две переменные), перекрывает в пределах набора назначенных
b, a
переменные идут слева направо, что иногда приводит к путанице. Например,
следующая программа печатает [0, 2]
:
х = [0, 1] я = 0 i, x [i] = 1, 2 # i обновляется, затем x [i] обновляется печать (х)
См. Также
- PEP 3132 - Расширенная итерационная распаковка
Спецификация для функции
* target
.
7.2.1. Операторы расширенного присваивания
Расширенное присваивание - это комбинация в одном операторе двоичного
операция и заявление о присвоении:
augmented_assignment_stmt :: =augtarget
augop
(expression_list
|yield_expression
) augtarget :: =идентификатор
|attributeref
|подписка
|нарезка
августа :: = "+ =" | "- =" | "* =" | "@ =" | "/ =" | "// =" | "% =" | знак равно | ">> =" | "<< =" | "& =" | "^ =" | "| ="
(См. Раздел "Основные" для определения синтаксиса последних трех
символы.)
Расширенное назначение оценивает цель (которая, в отличие от обычного
операторы, не могут быть распаковкой) и список выражений, выполняет двоичный
операция, специфичная для типа присваивания двух операндов, и присваивает
результат к исходной цели. Цель оценивается только один раз.
Расширенное выражение присваивания, такое как x + = 1
, можно переписать как x = x +
для достижения аналогичного, но не совсем равного эффекта. В расширенном
1
версия, x
оценивается только один раз.Также, по возможности, фактическая операция
выполняется на месте , что означает, что вместо создания нового объекта и
присваивая это цели, вместо этого модифицируется старый объект.
В отличие от обычных заданий, расширенные задания оценивают левую часть
до , оценивая правую часть. Например, a [i] + = f (x)
сначала
ищет a [i]
, затем оценивает f (x)
и выполняет сложение, и
наконец, он записывает результат обратно в a [i]
.
За исключением назначения кортежам и нескольким целевым объектам в одном
оператор, присваивание, выполняемое операторами расширенного присваивания, обрабатывается
так же, как и обычные задания. Аналогично, за исключением возможных
на месте , двоичная операция, выполняемая с помощью расширенного присваивания
то же, что и обычные бинарные операции.
Для целей, которые являются ссылками на атрибуты, то же предостережение относительно класса
и атрибуты экземпляра применяются как для обычных назначений.
7.2.2. Аннотированные операторы присваивания
Назначение аннотации - это комбинация в одном
оператор, аннотации переменной или атрибута и необязательный оператор присваивания:
annotated_assignment_stmt :: =augtarget
":"выражение
["=" (звездное_выражение
|yield_expression
)]
Отличие от обычных операторов присваивания заключается в том, что разрешена только одна цель.
Для простых имен в качестве целей назначения, если они находятся в области класса или модуля,
аннотации оцениваются и сохраняются в специальном классе или модуле
атрибут __annotations__
это отображение словаря из имен переменных (искаженных, если частные) в
оцененные аннотации. Этот атрибут доступен для записи и автоматически
создается в начале выполнения тела класса или модуля, если аннотации
находятся статически.
Для выражений в качестве целей присваивания аннотации оцениваются, если
в области класса или модуля, но не хранится.
Если имя аннотировано в области действия функции, то это имя является локальным для
этот объем. Аннотации никогда не оцениваются и не сохраняются в областях действия.
Если правая сторона присутствует, аннотированный
присваивание выполняет фактическое присваивание перед оценкой аннотаций
(где применимо). Если правая часть отсутствует в выражении
target, то интерпретатор оценивает цель, кроме последнего
__setitem __ ()
или __setattr __ ()
вызов.
См. Также
- PEP 526 - Синтаксис для аннотаций переменных
Предложение, добавляющее синтаксис для аннотирования типов переменных
(включая переменные класса и переменные экземпляра) вместо выражения
их через комментарии.- PEP 484 - Подсказки по типу
Предложение, добавляющее модуль
набора
для обеспечения стандарта
синтаксис для аннотаций типов, который можно использовать в инструментах статического анализа и
Иды.
Изменено в версии 3.8: Теперь аннотированные присваивания позволяют использовать те же выражения в правой части, что и
регулярные задания. Ранее некоторые выражения (например, без скобок
выражения кортежа) вызвали синтаксическую ошибку.
7.3.
утверждение
утверждение
Операторы
Assert - удобный способ вставки утверждений отладки в
программа:
assert_stmt :: = "assert"выражение
[","выражение
]
Простая форма assert expression
эквивалентна
, если __debug__: если не выражение: поднять AssertionError
Расширенная форма, assert выражение1, выражение2
, эквивалентно
, если __debug__: если не выражение1: поднять ошибку AssertionError (выражение2)
Эти эквиваленты предполагают, что __debug__
и AssertionError
относятся к
встроенные переменные с этими именами.В текущей реализации
встроенная переменная __debug__
- True
при нормальных обстоятельствах,
Ложь
при запросе оптимизации (параметр командной строки -O
). Электрический ток
генератор кода не генерирует код для утверждения утверждения, когда оптимизация
запрашивается во время компиляции. Обратите внимание, что указывать источник необязательно.
код для выражения, которое не удалось в сообщении об ошибке; это будет отображаться
как часть трассировки стека.
Назначение __debug__
незаконно.Значение встроенной переменной
определяется при запуске интерпретатора.
7,4.
проездной
выписка
pass_stmt :: = "пройти"
проход
- это нулевая операция - при ее выполнении ничего не происходит.
Это полезно в качестве заполнителя, когда оператор требуется синтаксически, но не
код необходимо выполнить, например:
def f (arg): передать # функцию, которая (пока) ничего не делает class C: передать # класс без методов (пока)
7.5. Выписка
del
del_stmt :: = "del" target_list
Удаление определяется рекурсивно, очень похоже на способ определения присваивания.
Вместо того, чтобы подробно описывать это, вот несколько советов.
При удалении целевого списка рекурсивно удаляются все целевые объекты слева направо.
Удаление имени удаляет привязку этого имени к локальному или глобальному
пространство имен, в зависимости от того, встречается ли имя в глобальном операторе
в том же блоке кода.Если имя не привязано, возникает исключение NameError
.
будет поднят.
Удаление ссылок на атрибуты, подписок и срезов передается в
задействованный первичный объект; удаление среза в общем эквивалентно
присвоение пустого среза правильного типа (но даже это определяется
нарезанный объект).
Изменено в версии 3.2: Ранее было запрещено удалять имя из локального пространства имен, если оно
встречается как свободная переменная во вложенном блоке.
7,6.
возврат
выписка
return_stmt :: = "return" [ список_выражений
]
return
может встречаться только синтаксически вложенным в определение функции,
не в определении вложенного класса.
Если список выражений присутствует, он оценивается, иначе Не заменяется
.
return
оставляет текущий вызов функции со списком выражений (или
Нет
) в качестве возвращаемого значения.
Когда return
передает управление из оператора try
с
, наконец,
, что , наконец,
, выполняется до
действительно оставив функцию.
В функции генератора оператор return
указывает, что
генератор готов и вызовет повышение StopIteration
. Вернувшийся
значение (если есть) используется в качестве аргумента для создания StopIteration
и
становится StopIteration.значение
атрибута.
В функции асинхронного генератора пустой оператор return
указывает, что асинхронный генератор готов и вызовет
StopAsyncIteration
, который нужно поднять. Непустой возврат
оператор является синтаксической ошибкой в функции асинхронного генератора.
7,7. Отчет
yield
yield_stmt :: = yield_expression
Оператор yield
семантически эквивалентен yield
выражение.В операторе yield можно опустить круглые скобки.
что в противном случае потребовалось бы в эквивалентном выражении yield
утверждение. Например, операторы доходности
yieldдоход от
эквивалентны операторам выражения yield
(yield) (доход от )
Выражения и операторы Yield используются только при определении генератора
функции и используются только в теле функции генератора.Использование yield
в определении функции достаточно, чтобы это определение создало
функция генератора вместо нормальной функции.
Для получения полной информации о семантике yield
см.
Раздел выражений доходности.
7,8. Операция повышения
raise_stmt :: = "raise" [выражение
["из"выражение
]]
Если никаких выражений нет, raise
повторно вызывает последнее исключение
который был активен в текущей области.Если в текущем
области, возникает исключение RuntimeError
, указывающее, что это
ошибка.
В противном случае, raise
оценивает первое выражение как исключение.
объект. Это должен быть подкласс или экземпляр BaseException
.
Если это класс, экземпляр исключения будет получен при необходимости
создание экземпляра класса без аргументов.
Тип исключения - это класс экземпляра исключения,
значение - это сам экземпляр.
Объект трассировки обычно создается автоматически при возникновении исключения.
и прикреплен к нему как атрибут __traceback__
, который доступен для записи.
Вы можете создать исключение и установить собственную трассировку за один шаг, используя
with_traceback ()
метод исключения (который возвращает то же исключение
экземпляр, с его трассировкой, установленной для его аргумента), например:
возбудить исключение ("произошло foo"). With_traceback (tracebackobj)
Предложение из
используется для цепочки исключений: если задано, второе
Выражение должно быть другим классом исключения или экземпляром.Если второй
выражение является экземпляром исключения, оно будет прикреплено к поднятому
исключение как атрибут __cause__
(который доступен для записи). Если
выражение является классом исключения, будет создан экземпляр класса и
полученный экземпляр исключения будет прикреплен к поднятому исключению как
__cause__
атрибут. Если возникшее исключение не обрабатывается, оба
будут напечатаны исключения:
>>> попробуйте: ... печать (1/0) ... кроме Exception as exc: ... поднять RuntimeError ("Произошло что-то плохое") из exc ... Отслеживание (последний вызов последний): Файл "", строка 2, в ZeroDivisionError: деление на ноль Вышеупомянутое исключение явилось прямой причиной следующего исключения: Отслеживание (последний вызов последний): Файл " ", строка 4, в RuntimeError: Произошло что-то плохое
Подобный механизм работает неявно, если исключение возникает внутри
обработчик исключений или предложение finally
: предыдущее исключение
прикреплен как атрибут __context__
нового исключения:
>>> попробуйте: ... печать (1/0) ... Кроме: ... поднять RuntimeError ("Произошло что-то плохое") ... Отслеживание (последний вызов последний): Файл "", строка 2, в ZeroDivisionError: деление на ноль Во время обработки вышеуказанного исключения произошло другое исключение: Отслеживание (последний вызов последний): Файл " ", строка 4, в RuntimeError: Произошло что-то плохое
Цепочку исключений можно явно подавить, указав None
в
из пункта
:
>>> попробуйте: ... печать (1/0) ... Кроме: ... поднять RuntimeError ("Что-то плохое случилось") из None ... Отслеживание (последний вызов последний): Файл "", строка 4, в RuntimeError: Произошло что-то плохое
Дополнительную информацию об исключениях можно найти в разделе Исключения,
а информация об обработке исключений находится в разделе Оператор try.
Изменено в версии 3.3: Нет
теперь разрешено как Y
в поднять X с Y
.
Новое в версии 3.3: Атрибут __suppress_context__
для подавления автоматического отображения
контекст исключения.
7.9.
перерыв
выписка
break_stmt :: = "перерыв"
разрыв
может встречаться только синтаксически вложенным в для
или
, а цикл
, но не вложен в определение функции или класса в
этот цикл.
Завершает ближайший замыкающий цикл, пропуская дополнительный , иначе
предложение, если оно есть в цикле.
Если цикл для
завершается разрывом
, управление циклом
target сохраняет свое текущее значение.
Когда break
передает управление из оператора try
с
, наконец,
, что , наконец,
, выполняется до
действительно выходит из петли.
7.10.
продолжить
ведомость
continue_stmt :: = "продолжить"
продолжить
может встречаться только синтаксически вложенным в для
или
, а цикл
, но не вложен в определение функции или класса в
этот цикл.Он продолжается со следующего цикла ближайшего охватывающего цикла.
Когда continue
передает управление из оператора try
с
, наконец,
, что , наконец,
, выполняется до
действительно начало следующего цикла цикла.
7.11.
импорт
выписка
import_stmt :: = "import"module
["as"идентификатор
] (","module
["as"идентификатор
]) * | "from"relative_module
"import"идентификатор
["as"идентификатор
] ("," Идентификатор["как" идентификатор
]) * | "from"
relative_module
"import" "("идентификатор
["как"идентификатор
] ("," Идентификатор["как" идентификатор
]) * [","] ")" | "из"
relative_module
"импорт" "*" модуль :: = (идентификатор
".") *идентификатор
relative_module :: = "." *module
| "." +
Основной оператор импорта (№ из пункта
) выполняется в двух
шаги:
найти модуль, при необходимости загрузить и инициализировать
определяет имя или имена в локальном пространстве имен для области, в которой
появляется операторimport
.
Если оператор содержит несколько предложений (разделенных
запятые) два шага выполняются отдельно для каждого предложения, просто
как если бы статьи были разделены на отдельные статьи
заявления.
Детали первого шага, поиска и загрузки модулей описаны в
подробнее в разделе о системе импорта,
в котором также описаны различные типы пакетов и модулей, которые могут
быть импортированным, а также все хуки, которые можно использовать для настройки
система импорта. Обратите внимание, что сбои на этом этапе могут указывать на либо
что модуль не может быть найден, или что ошибка произошла во время
инициализация модуля, которая включает выполнение кода модуля.
Если запрошенный модуль получен успешно, он будет выполнен
доступен в локальном пространстве имен одним из трех способов:
Если после имени модуля идет
как
, то имя
следующий за, поскольку
привязан непосредственно к импортированному модулю.Если другое имя не указано, а импортируемый модуль является верхним
модуль уровня, имя модуля связано в локальном пространстве имен как
ссылка на импортированный модульЕсли импортируемый модуль , а не модуль верхнего уровня, то имя
пакета верхнего уровня, содержащего модуль, привязан к локальному
пространство имен как ссылка на пакет верхнего уровня.Импортированный модуль
должен быть доступен с использованием его полного квалифицированного имени, а не напрямую
Форма из
использует немного более сложный процесс:
найдите модуль, указанный в пункте
из
, загрузите и
инициализация при необходимости;для каждого из идентификаторов, указанных в пунктах
import
:проверьте, есть ли у импортированного модуля атрибут с таким именем
, если нет, попробуйте импортировать подмодуль с этим именем, а затем
еще раз проверьте импортированный модуль для этого атрибута, если атрибут не найден, возникает
ImportError
.в противном случае ссылка на это значение сохраняется в локальном пространстве имен,
используя имя вв качестве пункта
, если оно присутствует,
в противном случае используется имя атрибута
Примеры:
import foo # foo импортировано и привязано локально import foo.bar.baz # foo.bar.baz импортировано, foo привязано локально импортировать foo.bar.baz как fbb # foo.bar.baz импортировать и привязать как fbb from foo.bar import baz # foo.bar.baz импортирован и привязан как baz from foo import attr # foo import и foo.attr привязан как attr
Если список идентификаторов заменить звездочкой ( '*'
), все общедоступные
имена, определенные в модуле, привязаны к локальному пространству имен для области
где встречается оператор import
.
общедоступное имя , определенное модулем, определяется путем проверки его
пространство имен для переменной с именем __all__
; если определено, это должна быть последовательность
строк, которые являются именами, определенными или импортированными этим модулем. Имена
данные в __все__
считаются общедоступными и обязаны существовать.Если
__all__
не определено, набор публичных имен включает все найденные имена
в пространстве имен модуля, которые не начинаются с символа подчеркивания
( '_'
). __all__
должен содержать весь публичный API. Это предназначено
чтобы избежать случайного экспорта элементов, не являющихся частью API (например,
модули библиотеки, которые были импортированы и использовались внутри модуля).
Форма импорта с подстановочными знаками - из импорта модуля *
- разрешена только в
уровень модуля.Попытка использовать его в определениях классов или функций приведет к
вызвать SyntaxError
.
При указании импортируемого модуля необязательно указывать абсолютный
имя модуля. Когда модуль или пакет содержится в другом
package можно сделать относительный импорт в том же самом верхнем пакете
без упоминания имени пакета. Используя ведущие точки в
указанный модуль или пакет после из
вы можете указать, насколько высоко
пройти вверх по текущей иерархии пакетов без указания точных имен.Один
ведущая точка означает текущий пакет, в котором модуль, выполняющий импорт
существуют. Две точки означают повышение на один уровень пакета. Три точки - это два уровня вверх и т. Д.
Итак, если вы запустите из. импорт мода
из модуля в пакете pkg
тогда вы в конечном итоге импортируете pkg.mod
. Если вы запустите из ..subpkg2
из
import mod pkg.subpkg1
вы импортируете pkg.subpkg2.mod
.
Спецификация относительного импорта содержится в
раздел «Относительный импорт пакетов».
importlib.import_module ()
предоставляется для поддержки приложений, которые
динамически определять загружаемые модули.
Вызывает событие аудита import
с аргументами module
, filename
, sys.path
, sys.meta_path
, sys.path_hooks
.
7.11.1. Заявления о будущем
Оператор future - это директива компилятору, что конкретный
модуль должен быть скомпилирован с использованием синтаксиса или семантики, которые будут доступны в
указан будущий выпуск Python, в котором функция станет стандартной.
Заявление о будущем предназначено для облегчения перехода на будущие версии Python.
которые вносят несовместимые изменения в язык. Это позволяет использовать новые
функции для каждого модуля до выпуска, в котором функция становится
стандарт.
future_stmt :: = "from" "__future__" "import"feature
["as"идентификатор
] (","признак
["как" идентификатор]) * | "from" "__future__" "import" "("
особенность
["как"идентификатор
] ("," Функция["как" идентификатор
]) * [","] ")" функция :: =
идентификатор
Заявление о будущем должно появиться в верхней части модуля.Единственные строки, которые
могут появиться перед будущим выпиской:
Единственная функция, которая требует использования оператора future, - это
аннотации
(см. PEP 563 ).
Все исторические особенности, включенные в будущий отчет, по-прежнему распознаются
на Python 3. Список включает absolute_import
, раздел
,
генераторы
, generator_stop
, unicode_literals
,
print_function
, nested_scopes
и with_statement
.Они есть
все избыточны, потому что они всегда включены и сохраняются только в
обратная совместимость.
Отчет о будущем распознается и обрабатывается специально во время компиляции: Изменения
к семантике основных конструкций часто реализуются путем генерации
другой код. Может даже случиться так, что новая функция вводит новые
несовместимый синтаксис (например, новое зарезервированное слово), и в этом случае компилятор
может потребоваться разобрать модуль по-другому. Такие решения нельзя оттолкнуть
до времени выполнения.
Для любого данного выпуска компилятор знает, какие имена функций были определены,
и вызывает ошибку времени компиляции, если будущий оператор содержит функцию, не
ему известно.
Прямая семантика времени выполнения такая же, как и для любого оператора импорта: есть
стандартный модуль __future__
, описанный позже, и он будет импортирован в
обычным способом во время выполнения оператора future.
Интересная семантика времени выполнения зависит от конкретной функции, включенной в
будущее заявление.
Обратите внимание, что в выписке нет ничего особенного:
import __future__ [как имя]
Это не заявление о будущем; это обычный оператор импорта без
особая семантика или синтаксические ограничения.
Код, скомпилированный вызовами встроенных функций exec ()
и compile ()
которые происходят в модуле M
, содержащем оператор future, по умолчанию,
используйте новый синтаксис или семантику, связанную с оператором future.Это может
управляться необязательными аргументами для compile ()
- см. документацию
этой функции для получения подробной информации.
Будущее выражение, введенное в подсказке интерактивного интерпретатора, вступит в силу.
до конца сеанса переводчика. Если интерпретатор запускается с
-i
, передается имя сценария для выполнения, и сценарий включает
будущее заявление, оно будет действовать в интерактивном сеансе, запущенном
после выполнения сценария.
См. Также
- PEP 236 - Назад в __future__
Первоначальное предложение по механизму __future__.
7.12. Заявление
global
global_stmt :: = "global"идентификатор
(","идентификатор
) *
Оператор global
- это декларация, действующая для всего
текущий блок кода. Это означает, что перечисленные идентификаторы подлежат интерпретации.
как глобальные. Было бы невозможно присвоить глобальную переменную без
global
, хотя свободные переменные могут ссылаться на глобальные переменные, не будучи
объявлен глобальным.
Имена, перечисленные в операторе global
, не должны использоваться в одном коде.
текстовый блок, предшествующий этому глобальному оператору
.
Имена, перечисленные в глобальном операторе
, не должны определяться как формальные.
параметры или в для цели управления контурами
, класс
определение, определение функции, импорт
оператор или переменная
аннотация.
Детали реализации CPython: Текущая реализация не применяет некоторые из этих ограничений, но
программы не должны злоупотреблять этой свободой, поскольку будущие реализации могут потребовать
их или молча изменить смысл программы.
Примечание программиста: global
- это директива для синтаксического анализатора. Это
применяется только к коду, который анализируется одновременно с глобальным оператором
.
В частности, глобальный оператор
, содержащийся в строке или коде
объект, предоставленный встроенной функции exec ()
, не влияет на код
блок , содержащий вызов функции, а код, содержащийся в такой строке,
не зависит от глобальных операторов
в коде, содержащем функцию
вызов.То же самое относится к функциям eval ()
и compile ()
.
7,13. Нелокальный отчет
nonlocal_stmt :: = "нелокальный"идентификатор
(","идентификатор
) *
Нелокальный оператор
заставляет перечисленные идентификаторы ссылаться на
ранее связанные переменные в ближайшей охватывающей области, за исключением глобальных переменных.
Это важно, потому что поведение привязки по умолчанию - поиск
сначала локальное пространство имен.Оператор позволяет инкапсулированному коду повторно связывать
переменные вне локальной области видимости помимо глобальной (модульной) области.
Имена, перечисленные в нелокальной выписке
, в отличие от имен, перечисленных в
глобальный оператор
, должен ссылаться на уже существующие привязки в
охватывающая область (область, в которой должна быть создана новая привязка, не может
определяться однозначно).
Имена, перечисленные в нелокальном операторе
, не должны конфликтовать с
уже существующие привязки в локальной области.
См. Также
- PEP 3104 - Доступ к именам во внешних областях
Спецификация для нелокального оператора
Заявление возврата Python - AskPython
- Оператор возврата Python используется в функции для возврата чего-либо в вызывающую программу.
- Мы можем использовать оператор return только внутри функции.
- В Python каждая функция что-то возвращает.Если операторов возврата нет, возвращается Нет .
- Если оператор return содержит выражение, оно сначала вычисляется, а затем возвращается значение.
- Оператор return завершает выполнение функции.
- Функция может иметь несколько операторов возврата. Когда любой из них выполняется, функция завершается.
- Функция может возвращать несколько типов значений.
- Функция Python может возвращать несколько значений в одном операторе возврата.
Python Пример оператора return
Давайте посмотрим на простой пример сложения двух чисел и возврата суммы вызывающей стороне.
def add (x, y): итого = x + y общая сумма возврата
Мы можем оптимизировать функцию, указав выражение в операторе возврата.
def add (x, y): вернуть x + y
Каждая функция что-то возвращает
Давайте посмотрим, что возвращается, когда функция не имеет оператора возврата.
>>> def foo (): ... проходить ... >>> >>> print (foo ()) Никто >>>
Python Return Нет
Что происходит, если в операторе return ничего нет?
Если оператор return не имеет значения, функция возвращает Нет .
>>> def return_none (): ... возвращаться ... >>> печать (return_none ()) Никто >>>
Функции Python могут иметь несколько операторов возврата
def type_of_int (i): если я% 2 == 0: вернуть 'даже' еще: вернуть "нечетное"
Функция Python может возвращать значения нескольких типов.
В отличие от других языков программирования, функции Python не ограничиваются возвратом значений одного типа.Если вы посмотрите на определение функции, в нем нет никакой информации о том, что она может вернуть.
Давайте посмотрим на пример, в котором функция возвращает несколько типов значений.
def get_demo_data (object_type): если 'str' == object_type: вернуть "тест" elif 'tuple' == тип_объекта: возврат (1, 2, 3) elif 'list' == тип_объекта: return [1, 2, 3] elif 'dict' == тип_объекта: return {"1": 1, "2": 2, "3": 3} еще: return None
Возврат нескольких значений в одном операторе возврата
Мы можем вернуть несколько значений из одного оператора возврата.Эти значения разделяются запятой и возвращаются вызывающей программе в виде кортежа.
def return_multiple_values (): возврат 1, 2, 3 печать (return_multiple_values ()) print (тип (return_multiple_values ()))
Выход:
(1, 2, 3) <класс 'кортеж'>
Python возвращает несколько значений
Оператор return Python с блоком finally
Когда оператор return выполняется внутри блока try-except, сначала выполняется код блока finally перед возвратом значения вызывающей стороне.