Содержание
Передача аргументов функции
Теперь мы готовы узнать о том, как создать функцию, которая может получать доступ к аргументам, а также узнаем, как передать аргументы функции. Создадим простую функцию, которая может суммировать два числа:
Python
def add(a, b): return a + b
print( add(1, 2) ) # 3
1 2 3 4 |
defadd(a,b) returna+b print(add(1,2))# 3 |
Каждая функция выдает определенный результат. Если вы не указываете на выдачу конкретного результата, она, тем не менее, выдаст результат None (ничего). В нашем примере мы указали выдать результат a + b. Как вы видите, мы можем вызвать функцию путем передачи двух значений. Если вы передали недостаточно, или слишком много аргументов для данной функции, вы получите ошибку:
Python
add(1)
Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: add() takes exactly 2 arguments (1 given)
1 2 3 4 5 |
add(1) Traceback(most recent call last) File»<string>»,line1,in<fragment> TypeErroradd()takes exactly2arguments(1given) |
Вы также можете вызвать функцию, указав наименование аргументов:
Python
print( add(a = 2, b = 3) ) # 5
total = add(b = 4, a = 5) print(total) # 9
1 2 3 4 |
print(add(a=2,b=3))# 5 total=add(b=4,a=5) print(total)# 9 |
Стоит отметить, что не важно, в каком порядке вы будете передавать аргументы функции до тех пор, как они называются корректно. Во втором примере мы назначили результат функции переменной под названием total
Это стандартный путь вызова функции в случае, если вы хотите дальше использовать её результат.
Вы, возможно, подумаете: «А что, собственно, произойдет, если мы укажем аргументы, но они названы неправильно? Это сработает?» Давайте попробуем на примере:
Python
add(c=5, d=2)
Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: add() got an unexpected keyword argument ‘c’
1 2 3 4 5 |
add(c=5,d=2) Traceback(most recent call last) File»<string>»,line1,in<fragment> TypeErroradd()got an unexpected keywordargument’c’ |
Ошибка. Кто бы мог подумать? Это значит, что мы указали ключевой аргумент, который функция не распознала. Кстати, ключевые аргументы описана ниже.
Функции как объекты
Создавая объект функции оператором , как было показано в листинге 1, можно привязать созданный функциональный объект к имени в точности так же, как можно было бы привязать к этому имени число или строку . Этот пример подтверждает статус функций как объектов первого класса в Python. Функция в Python — это всего лишь ещё одно значение, с которым можно что-то сделать.
Наиболее частое действие, выполняемое с функциональными объектами первого класса, — это передача их во встроенные функции высшего порядка: , и . Каждая из этих функций принимает объект функции в качестве своего первого аргумента.
- применяет переданную функцию к каждому элементу в переданном списке (списках) и возвращает список результатов (той же размерности, что и входной);
- применяет переданную функцию к каждому значению в списке и ко внутреннему накопителю результата, например, означает (факториал);
- применяет переданную функцию к каждому элементу списка и возвращает список тех элементов исходного списка, для которых переданная функция вернула значение истинности.
Комбинируя эти три функции, можно реализовать неожиданно широкий диапазон операций потока управления, не прибегая к императивным утверждениям, а используя лишь выражения в функциональном стиле, как показано в листинге 2 (файл funcH.py из архива python_functional.tgz в разделе «Материалы для скачивания»):
Листинг 2. Функции высших порядков Python
#!/usr/bin/python # -*- coding: utf-8 -*- import sys def input_arg(): global arg arg = ( lambda: ( len( sys.argv ) > 1 and int( sys.argv ) ) or \ int( input( "число?: " ) ) )() return arg print( 'аргумент = {}'.format( input_arg() ) ) print( list( map( lambda x: x + 1, range( arg ) ) ) ) print( list( filter( lambda x: x > 4, range( arg ) ) ) ) import functools print( '{}! = {}'.format( arg, functools.reduce( lambda x, y: x * y, range( 1, arg ) ) ) )
Примечание. Этот код несколько усложнён по сравнению с предыдущим примером из-за следующих аспектов, связанных с совместимостью Python версий 2 и 3:
- Функция , объявленная как встроенная в Python 2, в Python 3 была вынесена в модуль и её прямой вызов по имени вызовет исключение , поэтому для корректной работы вызов должен быть оформлен как в примере или включать строку:
-
Функции и в Python 3 возвращают не список (что уже показывалось при обсуждении различий версий), а объекты-итераторы вида:
<map object at 0xb7462bec> <filter object at 0xb75421ac>
Для получения всего списка значений для них вызывается функция .
Поэтому такой код сможет работать в обеих версиях Python:
$ python3 funcH.py 7 аргумент = 7 7! = 720
Если переносимость кода между различными версиями не требуется, то подобные фрагменты можно исключить, что позволит несколько упростить код.
What is a function in Python?
In Python, a function is a group of related statements that performs a specific task.
Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organized and manageable.
Furthermore, it avoids repetition and makes the code reusable.
Syntax of Function
def function_name(parameters): """docstring""" statement(s)
Above shown is a function definition that consists of the following components.
- Keyword that marks the start of the function header.
- A function name to uniquely identify the function. Function naming follows the same .
- Parameters (arguments) through which we pass values to a function. They are optional.
- A colon (:) to mark the end of the function header.
- Optional documentation string (docstring) to describe what the function does.
- One or more valid python statements that make up the function body. Statements must have the same indentation level (usually 4 spaces).
- An optional statement to return a value from the function.
How to call a function in python?
Once we have defined a function, we can call it from another function, program or even the Python prompt. To call a function we simply type the function name with appropriate parameters.
Note: Try running the above code in the Python program with the function definition to see the output.
Функция xrange() в Python 2
Использование довольно популярно в Python 2.x ввиду создания итерируемого объекта, то есть цикла for или включения в виде , множества или словаря. Поведение напоминало работу генератора, то есть «ленивое вычисление», однако здесь итерация xrange не является исчерпывающей, то есть вы можете перебирать ее бесконечно.
Благодаря «ленивому вычислению», преимущество обычного в том, что обычно быстрее, если вы итерировали только раз (в цикле ). Однако по сравнению с одноразовыми итерациями, не рекомендуется повторять итерацию множество раз, так как каждый раз итерация начинается с нуля.
В Python 3 была имплементирована вместо . Функция больше использоваться не может, вызывая в Python 3 ошибку .
Python
import timeit
n = 10000 def test_range(n): return for i in range(n): pass
def test_xrange(n): for i in xrange(n): pass
1 2 3 4 5 6 7 8 9 10 |
importtimeit n=10000 deftest_range(n) returnforiinrange(n) pass deftest_xrange(n) foriinxrange(n) pass |
Python 2
Python
print ‘Python’, python_version()
print ‘\ntiming range()’ %timeit test_range(n)
print ‘\n\ntiming xrange()’ %timeit test_xrange(n)
1 2 3 4 5 6 7 8 |
print’Python’,python_version() print’\ntiming range()’ %timeittest_range(n) print’\n\ntiming xrange()’ %timeittest_xrange(n) |
Shell
Python 2.7.6
timing range() 1000 loops, best of 3: 433 µs per loop
timing xrange() 1000 loops, best of 3: 350 µs per loop
1 2 3 4 5 6 7 8 |
Python2.7.6 timing range() 1000loops,best of3433µsper loop timing xrange() 1000loops,best of3350µsper loop |
Python 3
Python
print(‘Python’, python_version())
print(‘\ntiming range()’) %timeit test_range(n)
1 2 3 4 |
print(‘Python’,python_version()) print(‘\ntiming range()’) %timeittest_range(n) |
Shell
Python 3.8.1
timing range() 1000 loops, best of 3: 520 µs per loop
1 2 3 4 |
Python3.8.1 timing range() 1000loops,best of3520µsper loop |
Python
print(xrange(10))
1 | print(xrange(10)) |
Shell
————————————————————————— NameError Traceback (most recent call last)
<ipython-input-5-5d8f9b79ea70> in <module>() —-> 1 print(xrange(10))
NameError: name ‘xrange’ is not defined
1 2 3 4 5 6 7 8 |
————————————————————————— NameError Traceback(most recent call last) <ipython-input-5-5d8f9b79ea70>in<module>() —->1print(xrange(10)) NameErrorname’xrange’isnotdefined |
Функции в Python
Функции в Python определяются 2-мя способами: через определение или через анонимное описание . Оба этих способа определения доступны, в той или иной степени, и в некоторых других языках программирования. Особенностью Python является то, что функция является таким же именованным объектом, как и любой другой объект некоторого типа данных, скажем, как целочисленная переменная. В листинге 1 представлен простейший пример (файл func.py из архива python_functional.tgz в разделе «Материалы для скачивания»):
Листинг 1. Определения функций
#!/usr/bin/python # -*- coding: utf-8 -*- import sys def show( fun, arg ): print( '{} : {}'.format( type( fun ), fun ) ) print( 'arg={} => fun( arg )={}'.format( arg, fun( arg ) ) ) if len( sys.argv ) > 1: n = float( sys.argv ) else: n = float( input( "число?: " ) ) def pow3( n ): # 1-е определение функции return n * n * n show( pow3, n ) pow3 = lambda n: n * n * n # 2-е определение функции с тем же именем show( pow3, n ) show( ( lambda n: n * n * n ), n ) # 3-е, использование анонимного описание функции
При вызове всех трёх объектов-функций мы получим один и тот же результат:
$ python func.py 1.3 <type 'function'> : <function pow3 at 0xb7662844> arg=1.3 => fun( arg )=2.197 <type 'function'> : <function <lambda> at 0xb7662bc4> arg=1.3 => fun( arg )=2.197 <type 'function'> : <function <lambda> at 0xb7662844> arg=1.3 => fun( arg )=2.197
Ещё более отчётливо это проявляется в Python версии 3, в которой всё является классами (в том числе, и целочисленная переменная), а функции являются объектами программы, принадлежащими к классу :
$ python3 func.py 1.3 <class 'function'> : <function pow3 at 0xb74542ac> arg=1.3 => fun( arg )=2.1970000000000005 <class 'function'> : <function <lambda> at 0xb745432c> arg=1.3 => fun( arg )=2.1970000000000005 <class 'function'> : <function <lambda> at 0xb74542ec> arg=1.3 => fun( arg )=2.1970000000000005
Примечание. Существуют ещё 2 типа объектов, допускающих функциональный вызов — функциональный метод класса и функтор, о которых мы поговорим позже.
Если функциональные объекты Python являются такими же объектами, как и другие объекты данных, значит, с ними можно и делать всё то, что можно делать с любыми данными:
- динамически изменять в ходе выполнения;
- встраивать в более сложные структуры данных (коллекции);
- передавать в качестве параметров и возвращаемых значений и т.д.
На этом (манипуляции с функциональными объектами как с объектами данных) и базируется функциональное программирование. Python, конечно, не является настоящим языком функционального программирования, так, для полностью функционального программирования существуют специальные языки: Lisp, Planner, а из более свежих: Scala, Haskell. Ocaml, … Но в Python можно «встраивать» приёмы функционального программирования в общий поток императивного (командного) кода, например, использовать методы, заимствованные из полноценных функциональных языков. Т.е. «сворачивать» отдельные фрагменты императивного кода (иногда достаточно большого объёма) в функциональные выражения.
Временами спрашивают: «В чём преимущества функционального стиля написания отдельных фрагментов для программиста?». Основным преимуществом функционального программирования является то, что после однократной отладки такого фрагмента в нём при последующем многократном использовании не возникнут ошибки за счёт побочных эффектов, связанных с присвоениями и конфликтом имён.
Достаточно часто при программировании на Python используют типичные конструкции из области функционального программирования, например:
print ( )
В результате запуска получаем:
$ python funcp.py
Область видимость и глобальные переменные
Концепт области (scope) в Пайтон такой же, как и в большей части языков программирования. Область видимости указывает нам, когда и где переменная может быть использована. Если мы определяем переменные внутри функции, эти переменные могут быть использованы только внутри это функции. Когда функция заканчиваются, их можно больше не использовать, так как они находятся вне области видимости. Давайте взглянем на пример:
Python
def function_a(): a = 1 b = 2 return a+b
def function_b(): c = 3 return a+c
print( function_a() ) print( function_b() )
1 2 3 4 5 6 7 8 9 10 11 12 |
deffunction_a() a=1 b=2 returna+b deffunction_b() c=3 returna+c print(function_a()) print(function_b()) |
Если вы запустите этот код, вы получите ошибку:
Python
NameError: global name ‘a’ is not defined
1 | NameErrorglobalname’a’isnotdefined |
Это вызвано тем, что переменная определенна только внутри первой функции, но не во второй. Вы можете обойти этот момент, указав в Пайтоне, что переменная а – глобальная (global). Давайте взглянем на то, как это работает:
Python
def function_a(): global a a = 1 b = 2 return a+b
def function_b(): c = 3 return a+c
print( function_a() ) print( function_b() )
1 2 3 4 5 6 7 8 9 10 11 12 13 |
deffunction_a() globala a=1 b=2 returna+b deffunction_b() c=3 returna+c print(function_a()) print(function_b()) |
Этот код работает, так как мы указали Пайтону сделать а – глобальной переменной, а это значит, что она работает где-либо в программе. Из этого вытекает, что это настолько же хорошая идея, насколько и плохая. Причина, по которой эта идея – плохая в том, что нам становится трудно сказать, когда и где переменная была определена. Другая проблема заключается в следующем: когда мы определяем «а» как глобальную в одном месте, мы можем случайно переопределить её значение в другом, что может вызвать логическую ошибку, которую не просто исправить.
Функции
Последнее обновление: 11.04.2018
Функции представляют блок кода, который выполняет определенную задачу и который можно повторно использовать в других частях программы. Формальное определение функции:
def имя_функции (): инструкции
Определение функции начинается с выражения def, которое состоит из имени функции, набора скобок с параметрами и двоеточия. Параметры в скобках необязательны. А со следующей строки идет блок инструкций, которые выполняет функция. Все инструкции функции имеют отступы от начала строки.
Например, определение простейшей функции:
def say_hello(): print("Hello")
Функция называется . Она не имеет параметров и содержит одну единственную инструкцию, которая выводит на консоль строку «Hello».
Для вызова функции указывается имя функции, после которого в скобках идет передача значений для всех ее параметров. Например:
def say_hello(): print("Hello") say_hello() say_hello() say_hello()
Здесь три раза подряд вызывается функция say_hello. В итоге мы получим следующий консольный вывод:
Hello Hello Hello
Теперь определим и используем функцию с параметрами:
def say_hello(name): print("Hello,",name) say_hello("Tom") say_hello("Bob") say_hello("Alice")
Функция принимает параметр name, и при вызове функции мы можем передать вместо параметра какой-либо значение:
Hello, Tom Hello, Bob Hello, Alice
Значения по умолчанию
Некоторые параметры функции мы можем сделать необязательными, указав для них значения по умолчанию при определении функции. Например:
def say_hello(name="Tom"): print("Hello,", name) say_hello() say_hello("Bob")
Здесь параметр name является необязательным. И если мы не передаем при вызове функции для него значение, то применяется значение по умолчанию, то есть строка «Tom».
Именованные параметры
При передаче значений функция сопоставляет их с параметрами в том порядке, в котором они передаются. Например, пусть есть следующая функция:
def display_info(name, age): print("Name:", name, "\t", "Age:", age) display_info("Tom", 22)
При вызове функции первое значение «Tom» передается первому параметру — параметру name, второе значение — число 22 передается второму параметру — age. И так далее по порядку. Использование именованных параметров позволяет переопределить порядок передачи:
def display_info(name, age): print("Name:", name, "\t", "Age:", age) display_info(age=22, name="Tom")
Именованные параметры предполагают указание имени параметра с присвоением ему значения при вызове функции.
Неопределенное количество параметров
С помощью символа звездочки можно определить неопределенное количество параметров:
def sum(*params): result = 0 for n in params: result += n return result sumOfNumbers1 = sum(1, 2, 3, 4, 5) # 15 sumOfNumbers2 = sum(3, 4, 5, 6) # 18 print(sumOfNumbers1) print(sumOfNumbers2)
В данном случае функция sum принимает один параметр — , но звездочка перед названием параметра указывает, что фактически на место этого параметра мы можем передать неопределенное количество значений или набор значений. В самой функции с помощью цикла for можно пройтись по этому набору и произвести с переданными значениями различные действия. Например, в данном случае возвращается сумма чисел.
Возвращение результата
Функция может возвращать результат. Для этого в функции используется оператор return, после которого указывается возвращаемое значение:
def exchange(usd_rate, money): result = round(money/usd_rate, 2) return result result1 = exchange(60, 30000) print(result1) result2 = exchange(56, 30000) print(result2) result3 = exchange(65, 30000) print(result3)
Поскольку функция возвращает значение, то мы можем присвоить это значение какой-либо переменной и затем использовать ее: .
В Python функция может возвращать сразу несколько значений:
def create_default_user(): name = "Tom" age = 33 return name, age user_name, user_age = create_default_user() print("Name:", user_name, "\t Age:", user_age)
Здесь функция create_default_user возвращает два значения: name и age. При вызове функции эти значения по порядку присваиваются переменным user_name и user_age, и мы их можем использовать.
Функция main
В программе может быть определено множество функций. И чтобы всех их упорядочить, хорошей практикой считается добавление специальной функции , в которой потом уже вызываются другие функции:
def main(): say_hello("Tom") usd_rate = 56 money = 30000 result = exchange(usd_rate, money) print("К выдаче", result, "долларов") def say_hello(name): print("Hello,", name) def exchange(usd_rate, money): result = round(money/usd_rate, 2) return result # Вызов функции main main()
НазадВперед
Docstrings
The first string after the function header is called the docstring and is short for documentation string. It is briefly used to explain what a function does.
Although optional, documentation is a good programming practice. Unless you can remember what you had for dinner last week, always document your code.
In the above example, we have a docstring immediately below the function header. We generally use triple quotes so that docstring can extend up to multiple lines. This string is available to us as the attribute of the function.
For example:
Try running the following into the Python shell to see the output.
To learn more about docstrings in Python, visit Python Docstrings.
Методы списков
len()
Метод возвращает длину объекта (списка, строки, кортежа или словаря).
принимает один аргумент, который может быть или последовательностью (например, строка, байты, кортеж, список, диапазон), или коллекцией (например, словарь, множество, frozenset).
list1 = # список print(len(list1)) # в списке 3 элемента, в выводе команды будет "3" str1 = 'basketball' # строка print(len(str1)) # в строке 9 букв, в выводе команды будет "9" tuple1 = (2, 3, 4, 5) # кортеж print(len(tuple1)) # в кортеже 4 элемента, в выводе команды будет "4" dict1 = {'name': 'John', 'age': 4, 'score': 45} # словарь print(len(dict1)) # в словаре 3 пары ключ-значение, в выводе команды будет "3"
index()
возвращает индекс элемента. Сам элемент передается методу в качестве аргумента. Возвращается индекс первого вхождения этого элемента (т. е., если в списке два одинаковых элемента, вернется индекс первого).
numbers = words = print(numbers.index(9)) # 4 print(numbers.index(2)) # 1 print(words.index("I")) # 0 print(words.index("JavaScript")) # возвращает ValueError, поскольку 'JavaScript' в списке 'words' нет
Первый результат очевиден. Второй и третий output демонстрируют возврат индекса именно первого вхождения.
Цифра «2» встречается в списке дважды, первое ее вхождение имеет индекс 1, второе — 2. Метод index() возвращает индекс 1.
Аналогично возвращается индекс 0 для элемента «I».
Если элемент, переданный в качестве аргумента, вообще не встречается в списке, вернется ValueError. Так получилось с попыткой выяснить индекс «JavaScript» в списке .
Опциональные аргументы
Чтобы ограничить поиск элемента конкретной подпоследовательностью, можно использовать опциональные аргументы.
words = print(words.index("am", 2, 5)) # 4
Метод index() будет искать элемент «am» в диапазоне от элемента с индексом 2 (включительно) до элемента с индексом 5 (этот последний элемент не входит в диапазон).
При этом возвращаемый индекс — индекс элемента в целом списке, а не в указанном диапазоне.
pop()
Метод удаляет и возвращает последний элемент списка.
Этому методу можно передавать в качестве параметра индекс элемента, который вы хотите удалить (это опционально). Если конкретный индекс не указан, метод удаляет и возвращает последний элемент списка.
Если в списке нет указанного вами индекса, метод выбросит exception .
cities = print "City popped is: ", cities.pop() # City popped is: San Francisco print "City at index 2 is : ", cities.pop(2) # City at index 2 is: San Antonio
Базовый функционал стека
Для реализации базового функционала стека в программах на Python часто используется связка метода pop() и метода append():
stack = [] for i in range(5): stack.append(i) while len(stack): print(stack.pop())
С этим читают
- Локальные и глобальные переменные
- Как в jquery имитировать печать текста
- Что такое tkinter
- Кортежи и операции с ними
- Функции input и print ввода/вывода
- Python урок 4. списки или массивы в питоне
- Python write file/ read file
- Возможности python 3, достойные того, чтобы ими пользовались
- Pep 8 — руководство по написанию кода на python
- Создание виртуальных окружений и установка библиотек для python 3 в ide pycharm