Функции и их аргументы | Python 3 для начинающих и чайников
В этой статье я планирую рассказать о функциях, именных и анонимных, инструкциях def, return и lambda, обязательных и необязательных аргументах функции, функциях с произвольным числом аргументов.
Именные функции, инструкция def
Функция в python — объект, принимающий аргументы и возвращающий значение. Обычно функция определяется с помощью инструкции def.
Определим простейшую функцию:
def add(x, y): return x + y
Инструкция return говорит, что нужно вернуть значение. В нашем случае функция возвращает сумму x и y.
Теперь мы ее можем вызвать:
>>> add(1, 10) 11 >>> add('abc', 'def') 'abcdef'
Функция может быть любой сложности и возвращать любые объекты (списки, кортежи, и даже функции!):
>>> def newfunc(n): ... def myfunc(x): ... return x + n ... return myfunc ... >>> new = newfunc(100) # new - это функция >>> new(200) 300
Функция может и не заканчиваться инструкцией return, при этом функция вернет значение None:
>>> def func(): ... pass ... >>> print(func()) None
Аргументы функции
Функция может принимать произвольное количество аргументов или не принимать их вовсе. Также распространены функции с произвольным числом аргументов, функции с позиционными и именованными аргументами, обязательными и необязательными.
>>> def func(a, b, c=2): # c - необязательный аргумент ... return a + b + c ... >>> func(1, 2) # a = 1, b = 2, c = 2 (по умолчанию) 5 >>> func(1, 2, 3) # a = 1, b = 2, c = 3 6 >>> func(a=1, b=3) # a = 1, b = 3, c = 2 6 >>> func(a=3, c=6) # a = 3, c = 6, b не определен Traceback (most recent call last): File "", line 1, in func(a=3, c=6) TypeError: func() takes at least 2 arguments (2 given)
Функция также может принимать переменное количество позиционных аргументов, тогда перед именем ставится *:
>>> def func(*args): ... return args ... >>> func(1, 2, 3, 'abc') (1, 2, 3, 'abc') >>> func() () >>> func(1) (1,)
Как видно из примера, args — это кортеж из всех переданных аргументов функции, и с переменной можно работать также, как и с кортежем.
Функция может принимать и произвольное число именованных аргументов, тогда перед именем ставится **:
>>> def func(**kwargs): ... return kwargs ... >>> func(a=1, b=2, c=3) {'a': 1, 'c': 3, 'b': 2} >>> func() {} >>> func(a='python') {'a': 'python'}
В переменной kwargs у нас хранится словарь, с которым мы, опять-таки, можем делать все, что нам заблагорассудится.
Анонимные функции, инструкция lambda
Анонимные функции могут содержать лишь одно выражение, но и выполняются они быстрее. Анонимные функции создаются с помощью инструкции lambda. Кроме этого, их не обязательно присваивать переменной, как делали мы инструкцией def func():
>>> func = lambda x, y: x + y >>> func(1, 2) 3 >>> func('a', 'b') 'ab' >>> (lambda x, y: x + y)(1, 2) 3 >>> (lambda x, y: x + y)('a', 'b') 'ab'
lambda функции, в отличие от обычной, не требуется инструкция return, а в остальном, ведет себя точно так же:
>>> func = lambda *args: args >>> func(1, 2, 3, 4) (1, 2, 3, 4)
Про Python — Справочник — def (функция/метод)
Последовательность инструкций, возвращающая некое значение.
В функцию могут быть переданы ноль и более аргументов, которые могут использоваться в теле функции.Для возврата значения из функции используется инструкция return
. Допускается использование нескольких return
, в том числе для раннего выхода из функции.
Функции без инструкции return
(равно как и с нею, но без указания аргумента) всё равно возвращают результат — None
.
Определение функции
Функцию можно определить при помощи ключевого слова def
, за которым должно следовать название функции и список её формальных параметров в круглых скобках. На следующих строках, выделенное отступом слева, должно располагаться тело функции.
Первой инструкцией в теле может быть литерал строки, который будет являться документацией для данной функции (строка документации — «docstring»). Некоторые утилиты и среды разработки используют такие строки для формирования интерактивной справки. Документировать код считается хорошим тоном.
def do_work(work, reverse=False):
"""Выполняет работу.В случае удачного выполнения, возвращает True,
иначе - False.
:param list work: Список для работы.
:param bool reverse: Флаг. Следует ли сделать
работу в обратном порядке
:rtype: bool
"""
В примере выше объявляется функция
do_work
, с формальными параметрами work
и reverse
. Функция задокументирована (испольузется формат описания сигнатуры reStructuredText). Кроме строки документации тело функции не содержит инструкций, тем не менее функция возвращает None
.Определение функции описывает пользовательский «объект функции» и является исполняемой инструкцией. В ходе исполнения происходит связывание имени функции в текущем локальном пространстве имён (локальной символьной таблице) с «объектом функции» — обёрткой вокруг исполняемого кода функции. Объект функции содержит ссылку на текущее глобальное пространство имён, которое будет использовано при вызове функции. Объект функции может быть в последующем связан и с другим именем (это можно использовать для переименования функций и создания псевдонимов).
Само определение функции не вызывает исполнения кода из тела функции. Код исполняется только при вызове функции.
def print_yes():
print('yes')print_yes() # yes
print_yes_alias = print_yes
print_yes_alias() # yes
Более того, ничто не мешает использовать «объект функции» как любой другой объект (например: передавать в функцию, использовать в качестве значения в словаре и т.п.).
def print_yes():
print('yes')def print_no():
print('no')
my_functions = [print_yes, print_no]
for function in my_functions:
# Переменная function будет содержать объект
# функции. Его-то мы и вызываем в следующей строке.
function()
В ходе исполнения функции формируется новая символьная таблица с локальными переменными функции: все назначения переменных оказываются в ней. При обращении к переменной, сначала производится попытка отыскать её в локальной символьной таблице, далее в таблицах обрамляющих функций, далее в глобальной таблице, и, наконец, в таблице встроенных имён.
Ввиду вышесказанного ссылаться на глобальные переменные внутри функции можно, а присвоить им значение (без использования инструкции global
) нельзя.
MY_GLOBAL = 1def set_global_1():
MY_GLOBAL = 2
def set_global_2():
global MY_GLOBAL
MY_GLOBAL = 2
print(MY_GLOBAL) # 1
set_global_1()
print(MY_GLOBAL) # 1
set_global_2()
print(MY_GLOBAL) # 2
В Питоне используется передача аргументов «по значению» (значением при этом всегда является ссылка на сам объект, но не на его значение). Однако, ввиду того, что в случаях, когда передаются изменяемые объекты, вызвавший увидит все изменения, сделанные вызываемым (например, при добавлении элементов в список), возможно лучше было бы назвать данный вид передачи «передачей по ссылке на объект».
def mutate_list(a_list):
a_list.append(0)
return Truemy_list = [1]
print(my_list) # [1]
mutate_list(my_list) # True
print(my_list) # [1, 0]
Когда функция вызывает другую функцию, для вызова создаётся новая локальная символьная таблица.
Вложенные определения
В Питоне можно вкладывать одно в другое не только определения функций (этим приёмом, в частости, пользуются при создании декораторов), но и классов (в случае необходимости).
def outer_func():# Определение функции внутри другой
# функции.
def inner_func():
return 'some'
return inner_func()
print(outer_func()) # some
def get_my_class():
# Определение класса внутри определения
# функции.
class MyClass:
my_attr = 1
return MyClass
my_class = get_my_class()
print(my_class.my_attr) # 1
Синонимы поиска: def (функция/метод), function, define, return, функции, procedure, вуа
синтаксис, логика и применение ~ PythonRu
Введение
Определение
Вот пример простой функции:
def compute_surface(radius):
from math import pi
return pi * radius * radius
Для определения функции нужно всего лишь написать ключевое слово def
перед ее именем, а после — поставить двоеточие. Следом идет блок инструкций.
Последняя строка в блоке инструкций может начинаться с return
, если нужно вернуть какое-то значение. Если инструкции
нет, тогда по умолчанию функция будет возвращать объект None
. Как в этом примере:
i = 0
def increment():
global i
i += 1
Функция инкрементирует глобальную переменную i
и возвращает None
(по умолчанию).
Вызовы
Для вызова функции, которая возвращает переменную, нужно ввести:
surface = compute_surface(1.)
Для вызова функции, которая ничего не возвращает:
increment()
Еще
Функцию можно записать в одну строку, если блок инструкций представляет собой простое выражение:
def sum(a, b): return a + b
Функции могут быть вложенными:
def func1(a, b):
def inner_func(x):
return x*x*x
return inner_func(a) + inner_func(b)
Функции — это объекты, поэтому их можно присваивать переменным.
Инструкция return
Возврат простого значения
Аргументы можно использовать для изменения ввода и таким образом получать вывод функции. Но куда удобнее использовать инструкцию return
, примеры которой уже встречались ранее. Если ее не написать, функция вернет значение None
.
Возврат нескольких значений
Пока что функция возвращала только одно значение или не возвращала ничего (объект None). А как насчет нескольких значений? Этого можно добиться с помощью массива. Технически, это все еще один объект. Например:
def stats(data):
"""данные должны быть списком"""
_sum = sum(data)
mean = sum / float(len(data))
variance = sum([(x-mean(data))**2/len(data) for x in data])
return mean,variance
m, v = stats([1, 2, 1])
Аргументы и параметры
В функции можно использовать неограниченное количество параметров, но число аргументов должно точно соответствовать параметрам. Эти параметры представляют собой позиционные аргументы. Также Python предоставляет возможность определять значения по умолчанию, которые можно задавать с помощью аргументов-ключевых слов.
Параметр — это имя в списке параметров в первой строке определения функции. Он получает свое значение при вызове. Аргумент — это реальное значение или ссылка на него, переданное функции при вызове. В этой функции:
def sum(x, y):
return x + y
x и y — это параметры, а в этой:
sum(1, 2)
1 и 2 — аргументы.
При определении функции параметры со значениями по умолчанию нужно указывать до позиционных аргументов:
def compute_surface(radius, pi=3.14159):
return pi * radius * radius
Если использовать необязательный параметр, тогда все, что указаны справа, должны быть параметрами по умолчанию.
Выходит, что в следующем примере допущена ошибка:
def compute_surface(radius=1, pi):
return pi * radius * radius
Для вызовов это работает похожим образом. Сначала нужно указывать все позиционные аргументы, а только потом необязательные:
S = compute_surface(10, pi=3.14)
На самом деле, следующий вызов корректен (можно конкретно указывать имя позиционного аргумента), но этот способ не пользуется популярностью:
S = compute_surface(radius=10, pi=3.14)
А этот вызов некорректен:
S = compute_surface(pi=3.14, 10)
При вызове функции с аргументами по умолчанию можно указать один или несколько, и порядок не будет иметь значения:
def compute_surface2(radius=1, pi=3.14159):
return pi * radius * radius
S = compute_surface2(radius=1, pi=3.14)
S = compute_surface2(pi=3.14, radius=10.)
S = compute_surface2(radius=10.)
Можно не указывать ключевые слова, но тогда порядок имеет значение. Он должен соответствовать порядку параметров в определении:
S = compute_surface2(10., 3.14)
S = compute_surface2(10.)
Если ключевые слова не используются, тогда нужно указывать все аргументы:
def f(a=1,b=2, c=3):
return a + b + c
Второй аргумент можно пропустить:
f(1,,3)
Чтобы обойти эту проблему, можно использовать словарь:
params = {'a':10, 'b':20}
S = f(**params)
Значение по умолчанию оценивается и сохраняется только один раз при определении функции (не при вызове). Следовательно, если значение по умолчанию — это изменяемый объект, например, список или словарь, он будет меняться каждый раз при вызове функции. Чтобы избежать такого поведения, инициализацию нужно проводить внутри функции или использовать неизменяемый объект:
def inplace(x, mutable=[]):
mutable.append(x)
return mutable
res = inplace(1)
res = inplace(2)
print(inplace(3))
[1, 2, 3]
def inplace(x, lst=None):
if lst is None: lst=[]
lst.append()
return lst
Еще один пример изменяемого объекта, значение которого поменялось при вызове:
def change_list(seq):
seq[0] = 100
original = [0, 1, 2]
change_list(lst1)
original
[100, 1, 2]
Дабы не допустить изменения оригинальной последовательности, нужно передать копию изменяемого объекта:
original = [0, 1, 2]
change_list(original[:])
original
[100, 1, 2]
Указание произвольного количества аргументов
Позиционные аргументы
Иногда количество позиционных аргументов может быть переменным. Примерами таких функций могут быть max()
и min()
. Синтаксис для определения таких функций следующий:
def func(pos_params, *args):
block statememt
При вызове функции нужно вводить команду следующим образом:
func(pos_params, arg1, arg2, ...)
Python обрабатывает позиционные аргументы следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает остальные позиционные аргументы в кортеж (*args), который можно использовать в функции.
Вот так:
def add_mean(x, *data):
return x + sum(data)/float(len(data))
add_mean(10,0,1,2,-1,0,-1,1,2)
10.5
Если лишние аргументы не указаны, значением по умолчанию будет пустой кортеж.
Произвольное количество аргументов-ключевых слов
Как и в случае с позиционными аргументами можно определять произвольное количество аргументов-ключевых слов следующим образом (в сочетании с произвольным числом необязательных аргументов из прошлого раздела):
def func(pos_params, *args, **kwargs):
block statememt
При вызове функции нужно писать так:
func(pos_params, kw1=arg1, kw2=arg2, ...)
Python обрабатывает аргументы-ключевые слова следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает другие позиционные аргументы в кортеж (*args), который можно использовать в функции (см. предыдущий раздел). В конце концов, он добавляет все лишние аргументы в словарь (**kwargs), который сможет использовать функция.
Есть функция:
def print_mean_sequences(**kwargs):
def mean(data):
return sum(data)/float(len(data))
for k, v in kwargs.items():
print k, mean(v)
print_mean_sequences(x=[1,2,3], y=[3,3,0])
y 2.0
x 2.0
Важно, что пользователь также может использовать словарь, но перед ним нужно ставить две звездочки (**):
print_mean_sequences(**{'x':[1,2,3], 'y':[3,3,0]})
y 2.0
x 2.0
Порядок вывода также не определен, потому что словарь не отсортирован.
Документирование функции
Определим функцию:
def sum(s,y): return x + y
Если изучить ее, обнаружатся два скрытых метода (которые начинаются с двух знаков нижнего подчеркивания), среди которых есть __doc__
. Он нужен для настройки документации функции. Документация в Python называется docstring
и может быть объединена с функцией следующим образом:
def sum(x, y):
"""Первая срока - заголовок
Затем следует необязательная пустая строка и текст
документации.
"""
return x+y
Команда docstring
должна быть первой инструкцией после объявления функции. Ее потом можно будет извлекать или дополнять:
print(sum.__doc__)
sum.__doc__ += "some additional text"
Методы, функции и атрибуты, связанные с объектами функции
Если поискать доступные для функции атрибуты, то в списке окажутся следующие методы (в Python все является объектом — даже функция):
sum.func_closure sum.func_defaults sum.func_doc sum.func_name
sum.func_code sum.func_dict sum.func_globals
И несколько скрытых методов, функций и атрибутов. Например, можно получить имя функции или модуля, в котором она определена:
>>> sum.__name__
"sum"
>>> sum.__module
"__main__"
Есть и другие. Вот те, которые не обсуждались:
sum.__call__ sum.__delattr__ sum.__getattribute__ sum.__setattr__
sum.__class__ sum.__dict__ sum.__globals__ sum.__new__ sum.__sizeof__
sum.__closure__ sum.__hash__ sum.__reduce__ sum.__str__
sum.__code__ sum.__format__ sum.__init__ sum.__reduce_ex__ sum.__subclasshook__
sum.__defaults__ sum.__get__ sum.__repr__
Рекурсивные функции
Рекурсия — это не особенность Python. Это общепринятая и часто используемая техника в Computer Science, когда функция вызывает сама себя. Самый известный пример — вычисление факториала n! = n * n — 1 * n -2 * … 2 *1. Зная, что 0! = 1, факториал можно записать следующим образом:
def factorial(n):
if n != 0:
return n * factorial(n-1)
else:
return 1
Другой распространенный пример — определение последовательности Фибоначчи:
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)
Рекурсивную функцию можно записать так:
def fibbonacci(n):
if n >= 2:
else:
return 1
Важно, чтобы в ней было была конечная инструкция, иначе она никогда не закончится. Реализация вычисления факториала выше, например, не является надежной. Если указать отрицательное значение, функция будет вызывать себя бесконечно. Нужно написать так:
def factorial(n):
assert n > 0
if n != 0:
return n * factorial(n-1)
else:
return 1
Важно!
Рекурсия позволяет писать простые и элегантные функции, но это не гарантирует эффективность и высокую скорость исполнения.
Если рекурсия содержит баги (например, длится бесконечно), функции может не хватить памяти. Задать максимальное значение рекурсий можно с помощью модуля sys
.
Глобальная переменная
Вот уже знакомый пример с глобальной переменной:
i = 0
def increment():
global i
i += 1
Здесь функция увеличивает на 1 значение глобальной переменной i
. Это способ изменять глобальную переменную, определенную вне функции. Без него функция не будет знать, что такое переменная i
. Ключевое слово global
можно вводить в любом месте, но переменную разрешается использовать только после ее объявления.
За редкими исключениями глобальные переменные лучше вообще не использовать.
Присвоение функции переменной
С существующей функцией func
синтаксис максимально простой:
variable = func
Переменным также можно присваивать встроенные функции. Таким образом позже есть возможность вызывать функцию другим именем. Такой подход называется непрямым вызовом функции.
Менять название переменной также разрешается:
def func(x): return x
a1 = func
a1(10)
10
a2 = a1
a2()
10
В этом примере a1, a2 и func
имеют один и тот же id. Они ссылаются на один объект.
Практический пример — рефакторинг существующего кода. Например, есть функция sq
, которая вычисляет квадрат значения:
def sq(x): return x*x
Позже ее можно переименовать, используя более осмысленное имя. Первый вариант — просто сменить имя. Проблема в том, что если в другом месте кода используется sq
, то этот участок не будет работать. Лучше просто добавить следующее выражение:
square = sq
Последний пример. Предположим, встроенная функция была переназначена:
dir = 3
Теперь к ней нельзя получить доступ, а это может стать проблемой. Чтобы вернуть ее обратно, нужно просто удалить переменную:
del dir
dir()
Анонимная функция: лямбда
Лямбда-функция — это короткая однострочная функция, которой даже не нужно имя давать. Такие выражения содержат лишь одну инструкцию, поэтому, например, if
, for
и while
использовать нельзя. Их также можно присваивать переменным:
product = lambda x,y: x*y
В отличие от функций, здесь не используется ключевое слово return
. Результат работы и так возвращается.
С помощью type()
можно проверить тип:
>>> type(product)
function
На практике эти функции редко используются. Это всего лишь элегантный способ записи, когда она содержит одну инструкцию.
power = lambda x=1, y=2: x**y
square = power
square(5.)
25
power = lambda x,y,pow=2: x**pow + y
[power(x,2, 3) for x in [0,1,2]]
[2, 3, 10]
Изменяемые аргументы по умолчанию
>>> def foo(x=[]):
... x.append(1)
... print x
...
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]
Вместо этого нужно использовать значение «не указано» и заменить на изменяемый объект по умолчанию:
>>> def foo(x=None):
... if x is None:
... x = []
... x.append(1)
... print x
>>> foo()
[1]
>>> foo()
[1]
Работаем с функциями в Python
Функция – это структура, которую вы определяете. Вам нужно решить, будут ли в ней аргументы, или нет. Вы можете добавить как аргументы ключевых слов, так и готовые по умолчанию. Функция – это блок кода, который начинается с ключевого слова def, названия функции и двоеточия, пример:
def a_function(): print(«You just created a function!»)
def a_function(): print(«You just created a function!») |
Эта функция не делает ничего, кроме отображения текста. Чтобы вызвать функцию, вам нужно ввести название функции, за которой следует открывающаяся и закрывающаяся скобки:
a_function() # You just created a function!
a_function() # You just created a function! |
Просто, не так ли?
Пустая функция (stub)
Иногда, когда вы пишете какой-нибудь код, вам нужно просто ввести определения функции, которое не содержит в себе код. Я сделал небольшой набросок, который поможет вам увидеть, каким будет ваше приложение. Вот пример:
def empty_function(): pass
def empty_function(): pass |
А вот здесь кое-что новенькое: оператор pass. Это пустая операция, это означает, что когда оператор pass выполняется, не происходит ничего.
Передача аргументов функции
Теперь мы готовы узнать о том, как создать функцию, которая может получать доступ к аргументам, а также узнаем, как передать аргументы функции. Создадим простую функцию, которая может суммировать два числа:
def add(a, b): return a + b print( add(1, 2) ) # 3
def add(a, b): return a + b
print( add(1, 2) ) # 3 |
Каждая функция выдает определенный результат. Если вы не указываете на выдачу конкретного результата, она, тем не менее, выдаст результат None (ничего). В нашем примере мы указали выдать результат a + b. Как вы видите, мы можем вызвать функцию путем передачи двух значений. Если вы передали недостаточно, или слишком много аргументов для данной функции, вы получите ошибку:
add(1) Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: add() takes exactly 2 arguments (1 given)
add(1)
Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: add() takes exactly 2 arguments (1 given) |
Вы также можете вызвать функцию, указав наименование аргументов:
print( add(a = 2, b = 3) ) # 5 total = add(b = 4, a = 5) print(total) # 9
print( add(a = 2, b = 3) ) # 5
total = add(b = 4, a = 5) print(total) # 9 |
Стоит отметить, что не важно, в каком порядке вы будете передавать аргументы функции до тех пор, как они называются корректно. Во втором примере мы назначили результат функции переменной под названием total. Это стандартный путь вызова функции в случае, если вы хотите дальше использовать её результат.
Вы, возможно, подумаете: «А что, собственно, произойдет, если мы укажем аргументы, но они названы неправильно? Это сработает?» Давайте попробуем на примере:
add(c=5, d=2) Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: add() got an unexpected keyword argument ‘c’
add(c=5, d=2)
Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: add() got an unexpected keyword argument ‘c’ |
Ошибка. Кто бы мог подумать? Это значит, что мы указали ключевой аргумент, который функция не распознала. Кстати, ключевые аргументы описана ниже.
> Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Открыть форум> Чат и Паблик Программистов
Присоединяйтесь к нашему чату в Телеграм и подпишитесь на наш паблик в ВК.
Ключевые аргументы
Функции также могут принимать ключевые аргументы. Более того, они могут принимать как регулярные, так и ключевые аргументы. Это значит, что вы можете указывать, какие ключевые слова будут ключевыми, и передать их функции. Это было в примере выше.
def keyword_function(a=1, b=2): return a+b print( keyword_function(b=4, a=5) ) # 9
def keyword_function(a=1, b=2): return a+b
print( keyword_function(b=4, a=5) ) # 9 |
Вы также можете вызвать данную функцию без спецификации ключевых слов. Эта функция также демонстрирует концепт аргументов, используемых по умолчанию. Каким образом? Попробуйте вызвать функцию без аргументов вообще!
Функция вернулась к нам с числом 3. Почему? Причина заключается в том, что а и b по умолчанию имеют значение 1 и 2 соответственно. Теперь попробуем создать функцию, которая имеет обычный аргумент, и несколько ключевых аргументов:
def mixed_function(a, b=2, c=3): return a+b+c mixed_function(b=4, c=5) Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: mixed_function() takes at least 1 argument (2 given)
def mixed_function(a, b=2, c=3): return a+b+c
mixed_function(b=4, c=5)
Traceback (most recent call last): File «<string>», line 1, in <fragment> TypeError: mixed_function() takes at least 1 argument (2 given) |
print( mixed_function(1, b=4, c=5) ) # 10 print( mixed_function(1) ) # 6
print( mixed_function(1, b=4, c=5) ) # 10
print( mixed_function(1) ) # 6 |
Выше мы описали три возможных случая. Проанализируем каждый из них. В первом примере мы попробовали вызвать функцию, используя только ключевые аргументы. Это дало нам только ошибку. Traceback указывает на то, что наша функция принимает, по крайней мере, один аргумент, но в примере было указано два аргумента. Что же произошло? Дело в том, что первый аргумент необходим, потому что он ни на что не указывает, так что, когда мы вызываем функцию только с ключевыми аргументами, это вызывает ошибку. Во втором примере мы вызвали смешанную функцию, с тремя значениями, два из которых имеют название. Это работает, и выдает нам ожидаемый результат: 1+4+5=10. Третий пример показывает, что происходит, если мы вызываем функцию, указывая только на одно значение, которое не рассматривается как значение по умолчанию. Это работает, если мы берем 1, и суммируем её к двум значениям по умолчанию: 2 и 3, чтобы получить результат 6! Удивительно, не так ли?
*args и **kwargs
Вы также можете настроить функцию на прием любого количества аргументов, или ключевых аргументов, при помощи особого синтаксиса. Чтобы получить бесконечное количество аргументов, мы используем *args, а чтобы получить бесконечное количество ключевых аргументов, мы используем *kwargs. Сами слова “args” и “kwargs” не так важны. Это просто сокращение. Вы можете назвать их *lol и *omg, и они будут работать таким же образом. Главное здесь – это количество звездочек. Обратите внимание: в дополнение к конвенциям *args и *kwargs, вы также, время от времени, будете видеть andkw. Давайте взглянем на следующий пример:
def many(*args, **kwargs): print( args ) print( kwargs ) many(1, 2, 3, name=»Mike», job=»programmer») # Результат: # (1, 2, 3) # {‘job’: ‘programmer’, ‘name’: ‘Mike’}
def many(*args, **kwargs): print( args ) print( kwargs )
many(1, 2, 3, name=»Mike», job=»programmer»)
# Результат: # (1, 2, 3) # {‘job’: ‘programmer’, ‘name’: ‘Mike’} |
Сначала мы создали нашу функцию, при помощи нового синтаксиса, после чего мы вызвали его при помощи трех обычных аргументов, и двух ключевых аргументов. Функция показывает нам два типа аргументов. Как мы видим, параметр args превращается в кортеж, а kwargs – в словарь. Вы встретите такой тип кодинга, если взгляните на исходный код Пайтона, или в один из сторонних пакетов Пайтон.
Область видимость и глобальные переменные
Концепт области (scope) в Пайтон такой же, как и в большей части языков программирования. Область видимости указывает нам, когда и где переменная может быть использована. Если мы определяем переменные внутри функции, эти переменные могут быть использованы только внутри это функции. Когда функция заканчиваются, их можно больше не использовать, так как они находятся вне области видимости. Давайте взглянем на пример:
def function_a(): a = 1 b = 2 return a+b def function_b(): c = 3 return a+c print( function_a() ) print( function_b() )
def function_a(): a = 1 b = 2 return a+b
def function_b(): c = 3 return a+c
print( function_a() ) print( function_b() ) |
Если вы запустите этот код, вы получите ошибку:
NameError: global name ‘a’ is not defined
NameError: global name ‘a’ is not defined |
Это вызвано тем, что переменная определенна только внутри первой функции, но не во второй. Вы можете обойти этот момент, указав в Пайтоне, что переменная а – глобальная (global). Давайте взглянем на то, как это работает:
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() )
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() ) |
Этот код работает, так как мы указали Пайтону сделать а – глобальной переменной, а это значит, что она работает где-либо в программе. Из этого вытекает, что это настолько же хорошая идея, насколько и плохая. Причина, по которой эта идея – плохая в том, что нам становится трудно сказать, когда и где переменная была определена. Другая проблема заключается в следующем: когда мы определяем «а» как глобальную в одном месте, мы можем случайно переопределить её значение в другом, что может вызвать логическую ошибку, которую не просто исправить.
Советы в написании кода
Одна из самых больших проблем для молодых программистов – это усвоить правило «не повторяй сам себя». Суть в том, что вы не должны писать один и тот же код несколько раз. Когда вы это делаете, вы знаете, что кусок кода должен идти в функцию. Одна из основных причин для этого заключается в том, что вам, вероятно, придется снова изменить этот фрагмент кода в будущем, и если он будет находиться в нескольких местах, вам нужно будет помнить, где все эти местоположения И изменить их.
Сайт doctorsmm.com предлагает Вам персональные предложения по покупке лайков в ВК к постам и публикациям. Здесь Вы найдете дешевые цены на услуги, а также различные критерии, подходящие к любой ситуации. На сервисе также доступно приобретение репостов, голосов в голосования и опросы сети.
Копировать и вставлять один и тот же кусок кода – хороший пример спагетти-кода. Постарайтесь избегать этого так часто, как только получится. Вы будете сожалеть об этом в какой-то момент либо потому, что вам придется все это исправлять, либо потому, что вы столкнетесь с чужим кодом, с которым вам придется работать и исправлять вот это вот всё.
Подведем итоги
Теперь вы обладаете основательными знаниями, которые необходимы для эффективной работы с функциями. Попрактикуйтесь в создании простых функций, и попробуйте обращаться к ним различными способами.
Python 3: функции (def) — объявление и вызов
Вот мы с вами и подошли к одному из фундаментальных моментов в изучении языка Python – функциям. Что это такое? Смотрите. Например, уже знакомая вам функция
print()
выводит сообщения в консоль. Фактически же при ее вызове выполняется определенный фрагмент программы, результатом которого и является вывод информации в заданном виде. И это очень удобно. Благодаря наличию таких функций нам не нужно каждый раз писать дублирующие инструкции для выполнения типовых операций. Собственно, это главное предназначение функций – многократное выполнение определенного фрагмента программы.
Язык Python позволяет программисту создавать свои собственные функции. Для этого используется следующий синтаксис:
def <имя функции>([список аргументов]):
оператор 1
оператор 2
…
оператор
N
Здесь имя функции придумывается программистом подобно именам переменных и, так как функция – это определенное действие, то ее имя следует выбирать как глагол, например:
go, show, get, set и т.п.
Далее, идет набор операторов, которые образуют тело функции. Именно они начинают выполнятся при ее вызове.
Давайте зададим простейшую функцию, которая будет выводить «hello» в консоль:
def sayHello(): print("hello")
Смотрите, мы здесь придумали имя функции «sayHello», записали пустые круглые скобки без аргументов и через двоеточие определили тело функции в виде конструкции print(«hello»). Но это лишь определение функции. Самого вызова здесь еще нет и если запустить программу, то ничего не произойдет.
Чтобы вызвать эту функцию, нужно указать ее имя и в конце обязательно поставить круглые скобки даже если мы не передаем ей никаких аргументов:
Эти круглые скобки являются оператором вызова функции с указанным именем. Теперь, при запуске программы в консоли появится сообщение «hello».
Имя функции без круглых скобок – это фактически ссылка на функцию:
то есть, ссылка на специальный объект, представляющий ту или иную функцию. А раз это ссылка, то мы можем выполнить такую операцию:
тем самым определить ее синоним и вызвать ее уже через это второе имя:
Как мы говорили в самом начале, функции, как правило, создаются для их многократного вызова. И действительно, мы теперь, можем ее вызывать в любом месте нашей программы необходимое число раз, например, так:
sayHello() print("---------------") sayHello()
Здесь будет уже два вызова этой функции. И так далее. Причем, обратите внимание, мы вызываем функцию только после ее определения. То есть, если записать ее вызвать в самом начале программы, то возникнет ошибка, т.к. данная функция не была определена. Это вроде как:
«сначала нужно испечь пирог и только потом можно его есть.»
Также и с функциями: мы их сначала определяем и только потом можем вызывать. Поэтому определение функций обычно идет в самом начале, а потом уже их вызовы в основной программе.
Если нужно определить еще одну функцию, то мы ее можем записать после первой:
def myAbs(x): x = -x if(x<0) else x
Имена функций должны быть уникальными (также как и имена переменных), поэтому я назвал ее myAbs, т.к. функция abs уже существует. И предполагаю, что она будет вычислять модуль переданного ей числа. Соответственно, в круглых скобках обозначаю этот аргумент. Если теперь мы ее вызовем:
то увидим значение None. Это произошло потому, что функция myAbs явно не возвращает никакого значения. По идее, мы ожидаем возврата переменной x. Для этого нужно записать оператор return, после которого через пробел указываем возвращаемую величину:
def myAbs(x): x = -x if(x<0) else x return x
Теперь, при вызове функции, получим ожидаемое значение 5. Как это в деталях работает? Вызывая функцию с аргументом -5, переменная x начинает ссылаться на этот числовой объект. Далее, выполняется тело функции и идет проверка: если x<0, то x=-x (меняем знак числа), иначе x не меняется. Затем, выполняется оператор return и функция myAbs возвращает вычисленное значение x.
Такой подход позволяет передавать функции самые разные значения, например, так:
print( myAbs(15) ) a = 100 print( myAbs(a) )
И это делает ее работу универсальной – с любыми числовыми данными. Причем, как только встречается оператор return функция завершает свою работу. То есть, если после данного оператора будут идти еще какие-либо конструкции:
def myAbs(x): x = -x if(x<0) else x return x print(x)
То при вызове этой функции:
Ничего в консоль выведено не будет, т.к. вызов был завершен на операторе return. А вот если поставить print до этого оператора:
def myAbs(x): x = -x if(x<0) else x print(x) return x
то мы увидим значение 5.8. Используя эту особенность, можно определять такие функции:
def isPositive(x): if x >=0: return True else: return False
В данном случае мы будем получать значения True для неотрицательных чисел и False – для отрицательных. И далее, ее можно использовать так:
p = [] for a in range(-5, 11): if isPositive(a): p.append(a) print(p)
В результате, список будет содержать только положительные числа. Правда, в данном случае, функцию можно записать гораздо короче:
def isPositive(x): return x >=0
Здесь сам оператор >= будет возвращать значение True или False.
Если нужно создать функцию, принимающую два аргумента, например, для вычисления площади прямоугольника, то это делается так:
def getSquare(w, h): return 2*(w+h)
То есть, аргументы перечисляются через запятую, а тело функции состоит всего из одного оператора return, в котором сразу выполняются необходимые вычисления.
Вызовем эту функцию:
p = getSquare(10, 5.5) print(p)
И увидим результат ее работы – значение 31,0. При этом, на первое значение 10 ссылается первый аргумент w, а на второе 5.5 – второй аргумент h. Вот так можно определять различное число аргументов у функций.
Далее, при вызове функций мы должны им передавать ровно столько параметров, сколько указано в их определении. Например, вот такие вызовы работать не будут:
myAbs() myAbs(1, 2) sayHello("abc")
Здесь указано или слишком много, или слишком мало фактических параметров.
Однако у любой функции можно добавить формальные параметры со значениями по умолчанию:
def sayHello(msg, end="!"): print(msg+end)
И теперь, можно вызвать эту функцию так:
или так:
Смотрите, если формальный параметр не указан, то берется его значение по умолчанию. Если же мы его явно задаем, то берется переданное значение. Здесь нужно помнить только одно правило: формальные аргументы должны быть записаны последними в списке аргументов функции. То есть, вот такая запись:
def sayHello(end="!", msg):
приведет к синтаксической ошибке.
Теперь, давайте добавим этой функции еще один вот такой формальный параметр:
def sayHello(msg, end="!", sep = ": "): print("Message"+sep+msg+end)
И функция будет выводить сообщение в формате: «Message»+sep+msg+end. Вызвать эту функцию мы можем таким образом:
sayHello("Hello", "?", " ")
и каждому параметру здесь будет соответствовать свое значение в соответствии с указанным порядком. А можно ли вызвать эту функцию, указав только первый и последний аргумент? Оказывается да, Python позволяет это делать. Вот таким образом:
sayHello("Hello", sep=" ")
Мы здесь вторым аргументом явно указываем имя формального параметра и присваиваем ему желаемое значение. В результате аргументы msg и sep будут принимать переданные значения, а аргумент end – значение по умолчанию. Это называется именованные параметры, когда мы указываем не просто значение, но еще и имя параметра.
Если нам требуется сразу вернуть несколько значений, то это можно сделать так. Предположим наша функция будет сразу определять и периметр и площадь прямоугольника:
def perAndSq(w, h): return 2*(w+h), w*h
И, далее, вызываем ее:
res = perAndSq(2.3, 5) print(res)
получаем результат в виде кортежа из двух чисел. Или, так:
per, sq = perAndSq(2.3, 5) print(per, sq)
Аналогичным образом можно возвращать и списки и словари и вообще любые типы данных.
Далее, в теле функции можно записывать самые разные конструкции языка Python. Например, для возведения числа в целую степень, можно определить такую функцию:
def myPow(x, n): sx = 1 while n > 0: sx *= x n -= 1 return sx
И, затем, вызвать ее:
Интересной особенностью Python в определении функций является возможность переопределять уже существующие функции. Например, у нас задана вот такая функция:
def sayHello(): print("hello")
Тогда ниже мы можем ее переопределить, если укажем то же самое имя:
def sayHello(): print("------- hello --------")
Теперь, при ее вызове:
увидим выполнение последнего, переопределенного варианта. Если дальше ее переопределить вот так:
def sayHello(msg): print(msg)
то все равно будет доступна только одна такая функция, но теперь уже с одним обязательным аргументом:
sayHello("привет мир")
Когда это может пригодиться на практике? Например, если мы хотим определить некоторую функцию в зависимости от условия:
TYPE_FUNC = True if TYPE_FUNC: def sayHello(): print("hello") else: def sayHello(msg): print(msg) sayHello()
Здесь при значении переменной TYPE_FUNC равной True будет определен первый вариант функции, а иначе – второй вариант. Иногда это бывает полезно.
Элементы функционального подохда к программированию
При написании программ приветствуется такой подход, который называется функциональным программированием. Продемонстрирую его на следующем примере. Предположим, нам нужна функция, которая находит максимальное значение из двух чисел:
def max2(a, b): if a > b: return a return b
И вызвать мы ее можем так:
Затем, нам потребовалась функция, которая бы находила максимальное из трех чисел. Как ее можно реализовать? Используя идею функционального программирования, это можно сделать следующим образом:
def max3(a, b, c): return max2(a, max2(b, c))
И вызвать так:
Смотрите, здесь оператор return возвращает значение, которое возвращает функция max2. Но, прежде чем она будет выполнена, вызовется другая функция max2, которая определит максимальное среди чисел b и c. То есть, прежде чем вызвать первую функцию max2 необходимо вычислить ее параметры: первый просто берется их x, а второй вычисляется вложенной функцией max2. Вот так это работает и вот что из себя представляет элемент функционального подхода к программированию.
Причем, благодаря гибкости языка Python, мы можем вызвать эту функцию и для нахождения максимальной строки:
print( max3("ab", "cd", "abc") )
так как строки могут спокойно сравниваться между собой. И вообще, любые величины, которые можно сравнивать на больше и меньше, можно подставлять в качестве аргументов функции max3 и max2.
Задания для самоподготовки
1. Задайте и вызовите функцию, которая вычисляет площадь прямоугольника.
2. Необходимо создать функцию, которая в зависимости от значения формального параметра type будет вычислять или площадь или периметр прямоугольника.
3. Написать функцию поиска максимального значения из переданного ей списка значений.
4. Написать функцию вычисления произведения значений элементов переданного ей списка.
def. Python 3 для начинающих
В языках программирования функции являются именованной частью кода. Это отдельные блоки в тексте программы. Определяются с помощью зарезервированного слова def. В Python к функциям можно обращаться неограниченное количество раз из любой части сценария.
Зачем нужны функции
Функции – это незаменимый инструмент программиста. С их помощью разработчик структурирует программу, делая ее понятней и компактнее. С помощью функций можно добиться многократного использования отдельной части кода без его повторного написания.
Это простейший способ упаковать логику выполнения отдельных частей программы. При этом сокращается объем и время, которое специалист тратит на создание сценария.
Как написать первую функцию
В Python 3 для начинающих свое знакомство с программированием есть самая простая функция print(). Чтобы увидеть ее в действии вам понадобится среда разработки. Для этого скачайте дистрибутив языка с официального сайта и установите Python на компьютер.
Откройте меню «Пуск» и в списке программ найдите Python 3. Разверните его щелчком левой клавиши. В открывшемся списке найдите среду IDLE и запустите ее. Наберите print(«Hello, World!») и нажмите «Ввод». Интерпретатор вернет результат вашей первой функции.
Некоторые программисты предпочитают работать в консоли. Если вы относитесь к их числу, нажмите win+R и введите команду python.exe. Откроется обычный интерпретатор, только с интерфейсом cmd. Наберите программу описанным выше образом и нажмите Enter в конце, чтобы увидеть результат.
Как использовать def
Новые функции создаются с помощью инструкции def. Они так же эффективны, как и встроенные print() или open(), но отличаются от функций в компилирующих языках. Python def относится к исполняемым инструкциям. Это означает, что функции не существует, пока интерпретатор ее не увидит, и не перейдет к ее исполнению.
Инструкция def создает новый объект и дает ему название. То есть когда интерпретатор приступает к реализации, он создает новый объект и связывает его с именем, указанным после def. Чтобы хранить данные к функциям можно прикреплять различные атрибуты.
Теперь давайте напишем функцию, возвращающую фразу «Hello, World!», только с использованием def:
- >>> def здравствуй_мир():
- print(«Hello, World!»)
- >>> здравствуй_мир() #вызов функции
- Hello, World!
Синтаксис функций и return
Инструкция def в Python состоит из заголовка и пишется по следующим правилам:
- >>>def <имя>(аргумент 1, аргумент 2, аргумент N):
После заголовка следует блок инструкций, который начинается с обязательного отступа. В IDLE интерпретатор сделает его автоматически. Но в блокноте или другом текстовом редакторе вы можете забыть нажать Tab. Тогда функция не запустится. Программный код в блоке инструкции называется телом функции и выполняется каждый раз при ее вызове.
Также в теле иногда находится return:
- def <имя>(аргумент 1, аргумент 2, аргумент N):
- …
- return <значение>
Return завершает работу функции и передает вызывающей программе объект-результат. Инструкция не является обязательной. Функция будет работать без return, и завершится, когда поток управления достигнет конца ее тела.
Параметры и аргументы
Каждой функции можно передавать параметры, которые указываются в скобках после def. В Python они записываются как переменные, разделенные запятыми. Значения или ссылки на объекты этим именам присваиваются в блоке за двоеточием. После операции присвоения их принято называть аргументами, а не параметрами.
Аргументы внутри функции никак не связаны с объектами вне ее, поэтому в программировании их относят к локальным переменным. Область видимости ограничена блоком функции, который начинается с def и заканчивается return. Чтобы было понятнее, приведем пример:
- x = 12 #присваиваем переменным ссылки на целочисленные объекты
- y = 34
- >>>def example(x,y): #создаем функцию с именем example
- x = «Hello» #присваиваем значения аргументам x, y
- y = «Python»
- print(x, y, sep= «, »)
- return None
- >>>example(x, y) #вызываем функцию, не забыв указать параметры
- Hello, Python
- >>>print(x, y)
- 12 34
Обратите внимание на предпоследнюю строчку кода. В интерпретаторе Python команда print() вернула переменные x и y из глобальной области видимости.
Значения аргументов не обязательно указывать внутри функции, можно их вписать вручную при ее вызове:
- >>>def E_2(x, y):
- return x + y
- >>>E_2(«Hello, » «Python!») #чтобы слова были разделены, поставьте пробел перед закрывающей кавычкой
- Hello, Python!
- E_2(5, 4)
- 10
Как видно из примера с простой функцией E_2, результат полностью зависит от типа объектов x и y. В первом случае E_2 выполнила конкатенацию, а во втором — арифметическую операцию сложения. В этом заключается принцип полиморфизма и динамической типизации. То, что объекты определяют синтаксический смысл, обуславливает гибкость и простоту языка. Не нужно тратить время на то, чтобы отдельно указать тип данных, с которым работает функция.
Правило LEGB
Это правило касается работы с переменными в разных областях видимости. По умолчанию все имена, которые вы создаете в теле функции, считаются локальными. А имена в модуле являются глобальными. При желании именам можно присвоить значение переменных верхнего уровня с помощью инструкции notlocal и global.
Правило LEGB объясняет схему разрешения имен:
- Как только интерпретатор находит переменную внутри инструкции def, он сначала выполняет поиск значений в локальной области видимости.
- Если поиск не дает результата, он переходит к области видимости любой всеобъемлющей инструкции def.
- Дальше интерпретатор двигается к глобальным именам в верхнем уровне модуля и тем, что обозначены как global.
- Если поиск не дает результатов, интерпретатор ищет имена во встроенной области видимости языка Python.
Рассмотрим наглядный пример:
- >>>L = 85
- >>>R = 23
- >>>def пример_2(K):
- R = 10
- C = L + K+R
- return C
- >>>пример_2(5)
- 100
Переменные L и R находятся на верхнем уровне и являются глобальными именами. R, C и K – это локальные переменные, так как присваивание значения происходит внутри инструкции def.
Интерпретатор сначала выполняет операцию сложения для локальных R, C и K, игнорируя переменную R вне инструкции def. Потом ищет L, и не найдя ее среди имен local, переходит на верхний уровень.
Что такое lambda
Помимо def, в Python функции можно создавать с помощью специальных выражений, одно из которых — lambda. Свое оригинальное название получила в честь лямбда-исчислений языка LISP.
Как и def, lambda создает функцию, которую можно будет в дальнейшем вызвать, но не связывает ее с каким-нибудь именем. На практике lambda используют, когда нужно отложить выполнение фрагмента кода.
Основы лямбда-выражений
По внешнему виду lambda-выражения напоминают инструкции def. Вначале пишется ключевое слово lambda, потом аргументы, двоеточие и само выражение:
- >>>f = lambda x, y, z: x + y + z
- >>>f(2, 3, 4)
- 9
Тело лямбда представляет собой одно единственное выражение, а не блок инструкций. За счет этого lambda ограничена в возможностях и не настолько универсальна как def. В ней может быть реализована только логика, без циклов while или for.
Для лямбда действуют аналогичные с def правила поиска переменных. Имена, указанные вне выражения, являются глобальными, внутри – локальными, и они никак не влияют друг на друга.
Lambda-выражения очень удобно встраивать в программу. За счет небольшого размера они минимизируют и упрощают код. Но использование лямбда не является принципиальным. В Python 3 начинающим для работы будет достаточно инструкции def.
Основы Python — кратко. Часть 5. Определение функций, основы. / Хабр
Начав писать главу про ООП, понял что совсем забыл освятить такой большой и нужный раздел Пайтона как функции. Тема это большая и обширная, потому, чтобы не сильно растягивать паузу между уроками, решил разделить ее на 2 части. Сначала расскажу основы, потом уже углубленные особенности Пайтоновского функциестроения.Функции в Пайтоне объявляются не просто, а очень просто. Вот пример самой простой:
def empty_func(): pass
Начинается объявление с ключевого слова def, что как не сложно догадаться является сокращением от define. После него идет имя функции. После имени в круглых скобках задается список параметров, в данном случае отсутствующих.
Тело функции пишется с отступом со следующей строки. учтите, что в Пайтоне функции с пустым телом запрещены, потому в качестве тела приведенной выше функции используется «пустой оператор» pass.
Теперь рассмотрим пример посерьезнее.
def safe_div(x, y): """Do a safe division :-) for fun and profit""" if y != 0: z = x / y print z return z else: print "Yippie-kay-yay, motherf___er!"
В этом примере есть несколько нововведений. первое, что бросается в глаза — это строка документации (docstring), идущая сразу после тела функции.
Обычно эта строка занимает не одну строку исходного текста (простите за каламбур) и потому задается в тройных кавычках. Она предназначена для описания функции, ее предназначения, параметров и т.п. Все хорошие ИДЕ умеют с этой строкой работать. Получить к ней доступ можно и из самой программы, используя свойство __doc__:
print safe_div.__doc__
Этим свойством (да, да, именно свойством, в Пайтоне даже функции на самом деле — классы) удобно пользоваться во время сеансов работы интерактивной консоли.
>>> from ftplib import FTP >>> print FTP.__doc__ An FTP client class. To create a connection, call the class using these argument: host, user, passwd, acct These are all strings, and have default value ''. Then use self.connect() with optional host and port argument. # дальнейшее почикано мною :-)
Вернемся к нашей исходной функции. Суть ее очень проста, она принимает 2 параметра: х и у. Если у не равен 0, она делит х на у, выводит результат на экран и возвращает свое частное в виде результата. Результат функции возвращают с помощью команды return. Благодаря механизму кортежей, описанному в прошлом уроке, функции в Пайтоне могут возвращать одновременно множество объектов.
Если же делитель все-таки равен нулю, функция выводит сообщение об ошибке. Неверно было бы предположить что в этом случае функция ничего не вернет. Правильнее будет сказать что функция вернет «ничего» 🙂 Иначе говоря, если в функции отсутствует оператор return, или же он вызван без параметров, то функция возвращает специальное значение None. В этом легко убедиться вызвав что-то типа print safe_div(10, 0).
Вот пример слегка посложнее, он взят из доклада-презентации Гвидо ван Россума.
def gcd(a, b): "Нахождение НОД" while a != 0: a,b = b%a,a # параллельное определение return b
Данная функция находит наибольший общий делитель двух чисел.
В общем, следует учитывать, что параметры в функции Пайтоном передаются по ссылке. Еще одним, возможно нетривиальным фактом к которому придется привыкать — является тот факт что сами функции являются значением, которое можно присваивать. Если воспользоваться нашей функцией safe_div для дальнейших экспериментов, то можно написать следующий код.
mystic_function = safe_div print mystic_function(10, 4)
Вот на этот раз и все, «за бортом» осталось еще много аспектов определения функций в Пайтоне, которые будут освещены в следующий раз.
Упражнения для проверки.
1. На основе существующей функции нахождения НОД, напишите функцию поиска НОК двух чисел.
2. Напишите подпрограмму табулирования функции, переданной в качестве аргумента. Так же аргументами задается начальное, конечное значение и шаг табуляции.
PS кстати, каков оптимальный объем «урока»? Что лучше — реже выходящие большие главы, или «лучше меньше да чаще».
Python-функций (def): определение с примерами
Что такое функция в Python?
В Python функция — это группа связанных операторов, выполняющих определенную задачу.
Функции помогают разбить нашу программу на более мелкие и модульные части. По мере того, как наша программа становится все больше и больше, функции делают ее более организованной и управляемой.
Кроме того, он позволяет избежать повторения и позволяет многократно использовать код.
Синтаксис функции
def имя_функции (параметры): «» «Строка документации» «» выписка (а)
Выше показано определение функции, которое состоит из следующих компонентов.
- Ключевое слово
def
, которое отмечает начало заголовка функции. - Имя функции для однозначной идентификации функции. Именование функций следует тем же правилам написания идентификаторов в Python.
- Параметры (аргументы), через которые мы передаем значения функции. Они не обязательны.
- Двоеточие (:) для обозначения конца заголовка функции.
- Необязательная строка документации (docstring), описывающая, что делает функция.
- Один или несколько допустимых операторов Python, составляющих тело функции.Заявления должны иметь одинаковый уровень отступа (обычно 4 пробела).
- Необязательный
return
оператор для возврата значения из функции.
Пример функции
def greet (имя):
«»»
Эта функция приветствует
человек прошел как
параметр
«»»
print («Привет,» + имя + «. Доброе утро!»)
Как вызвать функцию в Python?
После того, как мы определили функцию, мы можем вызвать ее из другой функции, программы или даже из командной строки Python.Чтобы вызвать функцию, мы просто набираем имя функции с соответствующими параметрами.
>>> привет ('Павел')
Привет, Пол. Доброе утро!
Примечание: Попробуйте запустить приведенный выше код в программе Python с определением функции, чтобы увидеть результат.
def greet (имя):
«»»
Эта функция приветствует
человек прошел как
параметр
«»»
print ("Привет," + имя + ". Доброе утро!")
привет ('Пол')
Строки документов
Первая строка после заголовка функции называется строкой документации и является сокращением от строки документации.Он кратко используется для объяснения того, что делает функция.
Хотя документация не является обязательной, это хорошая практика программирования. Если вы не помните, что ели на ужин на прошлой неделе, всегда документируйте свой код.
В приведенном выше примере у нас есть строка документации непосредственно под заголовком функции. Обычно мы используем тройные кавычки, чтобы строка документа могла занимать несколько строк. Эта строка доступна нам как атрибут функции __doc__
.
Например :
Попробуйте запустить в оболочке Python следующую команду, чтобы увидеть результат.
>>> печать (привет .__ doc__)
Эта функция приветствует
человек прошел как
параметр
Чтобы узнать больше о строках документации в Python, посетите Python Docstrings.
Заявление о возврате
Оператор return
используется для выхода из функции и возврата в то место, откуда она была вызвана.
Синтаксис возврата
возврат [список_выражений]
Этот оператор может содержать выражение, которое вычисляется и возвращается значение.Если в операторе нет выражения или самого оператора return
нет внутри функции, то функция вернет объект None
.
Например:
>>> print (привет («май»))
Привет, май. Доброе утро!
Нет
Здесь Нет
— это возвращаемое значение, поскольку greet ()
напрямую печатает имя, а оператор return
не используется.
Пример возврата
def absolute_value (число):
"" "Эта функция возвращает абсолютное
значение введенного числа "" "
если num> = 0:
вернуть номер
еще:
return -num
печати (absolute_value (2))
печать (абсолютное_значение (-4))
Выход
2 4
Как функция работает в Python?
Работа функций в PythonОбъем и время жизни переменных
Область действия переменной — это часть программы, в которой переменная распознается.Параметры и переменные, определенные внутри функции, не видны снаружи функции. Следовательно, они имеют локальный охват.
Время жизни переменной — это период, в течение которого переменная находится в памяти. Время жизни переменных внутри функции — до тех пор, пока функция выполняется.
Они уничтожаются, когда мы возвращаемся из функции. Следовательно, функция не запоминает значение переменной из своих предыдущих вызовов.
Вот пример, иллюстрирующий область действия переменной внутри функции.
def my_func ():
х = 10
print ("Значение внутри функции:", x)
х = 20
my_func ()
print ("Значение вне функции:", x)
Выход
Значение внутри функции: 10 Значение вне функции: 20
Здесь мы видим, что значение x изначально равно 20. Даже несмотря на то, что функция my_func ()
изменила значение x на 10, это не повлияло на значение вне функции.
Это связано с тем, что переменная x внутри функции отличается (локальная для функции) от переменной снаружи.Хотя у них одинаковые имена, это две разные переменные с разными областями действия.
С другой стороны, переменные вне функции видны изнутри. У них глобальный размах.
Мы можем читать эти значения изнутри функции, но не можем их изменять (записывать). Чтобы изменить значение переменных вне функции, они должны быть объявлены как глобальные переменные с использованием ключевого слова global
.
Типы функций
В принципе, мы можем разделить функции на следующие два типа:
- Встроенные функции — Функции, встроенные в Python.
- Пользовательские функции — Функции, определяемые самими пользователями.
функций Python
Функция — это блок кода, который выполняется только при вызове.
В функцию можно передавать данные, называемые параметрами.
В результате функция может возвращать данные.
Создание функции
В Python функция определяется с использованием def ключевое слово:
Пример
def my_function ():
print («Привет от функции»)
Вызов функции
Для вызова функции используйте имя функции, за которым следует скобка:
Пример
def my_function ():print («Привет от функции»)
my_function ()
Попробуй сам »Аргументы
Информация может передаваться в функции как аргументы.
Аргументы указываются после имени функции в круглых скобках. Вы можете добавить сколько угодно аргументов, просто разделив их запятыми.
В следующем примере есть функция с одним аргументом (fname). Когда функция вызывается, мы передаем имя, который используется внутри функции для вывода полного имени:
Пример
def my_function ( fname ):print (fname + «Refsnes»)
my_function ( «Emil» )
my_function ( «Tobias» )
my_function ( «Linus» )
Аргументы часто сокращаются до args в документации Python.
Параметры или аргументы?
Термины параметр и аргумент могут использоваться для одного и того же: информации, которая передается в функцию.
С точки зрения функции:
Параметр — это переменная, указанная в круглых скобках в определении функции.
Аргумент — это значение, которое отправляется функции при ее вызове.
Количество аргументов
По умолчанию функция должна вызываться с правильным количеством аргументов.Это означает, что если ваша функция ожидает 2 аргумента, вы должны вызвать функцию с 2 аргументами, не больше и не меньше.
Пример
Эта функция ожидает 2 аргумента и получает 2 аргумента:
def my_function (fname, lname):print (fname + «» + lname)
my_function («Emil», «Refsnes»)
Попробуй сам » Если вы попытаетесь вызвать функцию с 1 или 3 аргументами, вы получите ошибку:Пример
Эта функция ожидает 2 аргумента, но получает только 1:
def my_function (fname, lname):print (fname + «» + lname)
my_function («Emil»)
Попробуй сам »Произвольные аргументы, * args
Если вы не знаете, сколько аргументов будет передано вашей функции,
добавьте *
перед именем параметра в определении функции.
Таким образом, функция получит кортеж аргументов и сможет получить доступ к элементам соответственно:
Пример
Если количество аргументов неизвестно, добавьте перед именем параметра *
:
print («Самый младший ребенок is «+ kids [2])
my_function (» Эмиль «,» Тобиас «,» Линус «)
Попробуй сам »Произвольные аргументы часто сокращаются до * args в документации Python.
Аргументы ключевого слова
Вы также можете отправлять аргументы с синтаксисом ключ = значение .
Таким образом, порядок аргументов не имеет значения.
Пример
def my_function (child3, child2, child1):print («Самый младший ребенок is «+ child3»
my_function (child1 = «Emil», child2 = «Tobias», child3 = «Linus»)
Попробуй сам »Фраза Аргументы ключевого слова часто сокращается до kwargs в документации Python.
Аргументы произвольного ключевого слова, ** kwargs
Если вы не знаете, сколько аргументов ключевого слова будет передано в вашу функцию,
добавьте две звездочки: **
перед именем параметра в определении функции.
Таким образом, функция получит словарь аргументов и сможет получить доступ к элементам соответственно:
Пример
Если количество аргументов ключевого слова неизвестно, добавьте двойной **
перед именем параметра:
print («Его фамилия» + kid [«lname»])
my_function (fname = «Tobias», lname = «Refsnes»)
Попробуй сам »Произвольные аргументы Kword часто сокращаются до ** kwargs в документации Python.
Значение параметра по умолчанию
В следующем примере показано, как использовать значение параметра по умолчанию.
Если мы вызываем функцию без аргументов, она использует значение по умолчанию:
Пример
def my_function ( country = «Норвегия» ):print («Я из» + страна)
my_function («Швеция»)
my_function («Индия»)
my_function ()
my_function («Бразилия»)
Передача списка в качестве аргумента
Вы можете отправлять аргументы любых типов данных функции (строка, число, список, словарь и т. Д.).), и это будет обрабатываться как один и тот же тип данных внутри функции.
Например, если вы отправите список в качестве аргумента, он все равно будет списком, когда он достигает функции:
Пример
def my_function (food):для x в food:
print (x)
fruit = [«яблоко», «банан», «вишня»]
my_function (fruit)
Возвращаемые значения
Чтобы функция возвращала значение, используйте возврат
выписка:
Пример
def my_function (x):
return 5 * x
print (my_function (3))
print (my_function (5))
печать (моя_функция (9))
Пропуск Заявление
определение функции
не может быть пустым, но если
у вас по какой-то причине есть определение функции
без содержимого, введите оператор pass
, чтобы избежать ошибки.
Рекурсия
Python также принимает рекурсию функций, что означает, что определенная функция может вызывать сама себя.
Рекурсия — это общая математическая и программная концепция. Это означает, что функция вызывает сама себя. Преимущество этого заключается в том, что вы можете перебирать данные для достижения результата.
Разработчику следует быть очень осторожным с рекурсией, поскольку довольно легко ускользнуть от написания функции, которая никогда не завершается, или функции, которая использует избыточные объемы памяти или мощности процессора.Однако при правильном написании рекурсия может быть очень эффективным и математически элегантным подходом к программированию.
В этом примере tri_recursion () — это функция, которую мы определили для вызова самой себя («рекурсивная»). В качестве данных мы используем переменную k, которая уменьшается на (-1) каждый раз, когда мы выполняем рекурсию. Рекурсия заканчивается, когда условие не больше 0 (т.е. когда оно равно 0).
Новому разработчику может потребоваться некоторое время, чтобы понять, как именно это работает, лучший способ выяснить это — протестировать и изменить его.
Пример
Пример рекурсии
def tri_recursion (k):если (k> 0):
результат = k + tri_recursion (k — 1)
print (результат)
еще:
результат = 0
вернуть результат
print («\ n \ nРезультаты примера рекурсии»)
tri_recursion (6)
,
Что означает -> в определениях функций Python?
Переполнение стека- Товары
- Клиенты
- Случаи использования
- Переполнение стека Общественные вопросы и ответы
- Команды Частные вопросы и ответы для вашей команды
- предприятие Частные вопросы и ответы для вашего предприятия
- работы Программирование и связанные с ним возможности технической карьеры
- Талант Нанять технических талантов
- реклама Обратитесь к разработчикам по всему миру
4. Дополнительные инструменты управления потоком — документация Python 3.8.5
Помимо только что представленных операторов и
, Python использует обычный
операторы управления потоком, известные из других языков, с некоторыми особенностями.
4.1. if
Выписки
Возможно, наиболее известным типом операторов является оператор if
. Для
пример:
>>> x = int (input ("Пожалуйста, введите целое число:")) Введите целое число: 42 >>> если x <0: ,.. x = 0 ... print ('Отрицательное значение изменено на ноль') ... elif x == 0: ... print ('Ноль') ... elif x == 1: ... print ('Один') ... еще: ... print ('Подробнее') ... Больше
Может быть ноль или более частей elif
, а часть else
по желанию. Ключевое слово « elif
» является сокращением от «else if» и полезно
чтобы избежать чрезмерного вдавливания. , если
… elif
… elif
… последовательность заменяет переключатель
или case
операторов на других языках.
4.2. за
Выписки
Оператор для
в Python немного отличается от того, что вы можете использовать
в C или Паскаль. Вместо того, чтобы всегда повторять арифметическую прогрессию
чисел (как в Паскале), или давая пользователю возможность определять как
шаг итерации и условие остановки (как C), оператор Python для
перебирает элементы любой последовательности (список или строка) в том порядке, в котором
они появляются в последовательности. Например (без слов):
>>> # Измерьте несколько строк: ,.. words = ['кошка', 'окно', 'defenestrate'] >>> вместо w прописью: ... print (w, len (w)) ... кошка 3 окно 6 дефенестрат 12
Код, изменяющий коллекцию при повторении этой же коллекции, может сложно понять правильно. Вместо этого, как правило, проще использовать цикл над копией коллекции или для создания новой коллекции:
# Стратегия: итерация по копии для пользователя статус в users.copy (). items (): если статус == 'неактивен': del users [пользователь] # Стратегия: Создать новую коллекцию active_users = {} для пользователя статус в пользователях.Предметы(): если status == 'active': active_users [пользователь] = статус
4.3. Диапазон ()
Функция
Если вам нужно перебрать последовательность чисел, встроенная функция range ()
пригодится. Он генерирует арифметические прогрессии:
>>> для i в диапазоне (5): ... печать (я) ... 0 1 2 3 4
Данная конечная точка никогда не является частью сгенерированной последовательности; диапазон (10)
генерирует
10 значений, правовые индексы для элементов последовательности длиной 10.Это
можно разрешить диапазону начинаться с другого числа или указать другое
приращение (даже отрицательное; иногда это называется «шагом»):
диапазон (5, 10) 5, 6, 7, 8, 9 диапазон (0, 10, 3) 0, 3, 6, 9 диапазон (-10, -100, -30) -10, -40, -70
Для перебора индексов последовательности можно объединить range ()
и len ()
следующим образом:
>>> a = ['Мария', 'была', 'а', 'маленькая', 'барашка'] >>> для i в диапазоне (len (a)): ,.. print (i, a [i]) ... 0 Мэри 1 имел 2 а 3 маленькие 4 баранины
Однако в большинстве таких случаев удобно использовать enumerate ()
, см. Методы зацикливания.
Странная вещь происходит, если вы просто печатаете диапазон:
>>> печать (диапазон (10)) диапазон (0, 10)
Во многих отношениях объект, возвращаемый функцией range ()
, ведет себя так, как будто это список,
но на самом деле это не так. Это объект, который возвращает последовательные элементы
желаемую последовательность, когда вы повторяете ее, но на самом деле это не делает
список, тем самым экономя место.
Мы говорим, что такой объект является итеративным, то есть подходит в качестве цели для
функции и конструкции, которые ожидают чего-то, от чего они могут
приобретайте последовательные предметы, пока не закончится запас. Мы видели это
оператор for
является такой конструкцией, а пример функции
который требует итерации - sum ()
:
>>> сумма (диапазон (4)) # 0 + 1 + 2 + 3 6
Позже мы увидим больше функций, которые возвращают итерации и принимают итерации как аргументы.Наконец, возможно, вам интересно, как получить список из диапазона. Вот решение:
>>> список (диапазон (4)) [0, 1, 2, 3]
В главе «Структуры данных» мы более подробно обсудим список ()
.