Функции

Содержание
Введение
Пример
def
Hello World!
type hints
Параметры и аргументы
Типы аргументов
Аргументы по умолчанию
return
Области видимости
Встроенные функции
Вызываемые объекты
Похожие статьи

Пример использования

Создайте файл с раширением .py

Например functions_demo.py

Рассмотрим простейшую функцию, которая ничего не делает.

Чтобы её объявить используйте слово def затем придумайте название - например lazy поставьте круглые скобки () и двоеточие

Общий синтаксис следующий

def имя_функции(): какой-то код

В нашем случае получается

def lazy(): pass

pass означает просто продолжать код ничего не предпринимая. Он применяется далеко не во всех функциях.

Наша функция создана, иначе говоря объявлена. Это значит, что она существует где-то в коде и может что-то сделать.

Но не делает. Чтобы функция что-то делала её нужно вызвать. В нашем случае достаточно написать её имя и круглые скобки.

lazy()

python functions_demo.py

Если никаких ошибок не допущено вывод будет пустым

def

Ключевое слово def используется для определения новых функций.

Оно связывает объект функции с именем

Выполняется в runtime

Hello World!

Объявим и вызовем функцию, которая пишет Hello World!

def hello(): print("Hello World!") hello()

python functions_demo.py

Hello World!

Функцию не обязательно писать в одну строку. Лучше после двоеточия перейти на новую строку и сделать отступ из четырёх пробелов.

def hello(): print("Hello World!") hello()

python functions_demo.py

Hello World!

Напишем функцию, которая складывает два числа.

def sum(first, second): print(first + second) sum(3,4)

python functions_demo.py

7

type hints

В соответствии с PEP 484 рекомендуется указывать ожидаемые типы данных как для параметров, так и для возвращаемого значения

def sum(first: float, second: float) -> float: print(first + second) sum(3.0, 4.6)

python functions_demo.py

7.6

Никаких ограничений эти подсказки не накладывают. Можно спокойно выполнить

sum("a", "b")

python functions_demo.py

И получить

ab

Подсказки нужны скорее для сторонней проверки, каким-либо инструментом.

Параметры и аргументы

Параметры и аргументы это почти одно и то же, но термин параметры применяют во время объявления функции а аргументы в момент вызова.

В некоторых источниках вместо термина параметры используется термин формальные аргументы (formal arguments)

Проще всего понять на примере

def add(a, b): return a+b add(2, 3)

a и b это параметры, а 2 и 3 это аргументы

Типы аргументов

Аргументы могут передаваться как позиционные (positional) и как именованные (keyword).

Позиционные аргументы

Позиционные аргументы сопоставляются с параметрами (parameter или formal argument) в соответсвии с порядком следования.

Пример передачи двух позиционных аргументов

a = sub(2, 3)

Предположим, функция sub() вычитает из первого аргумента второй.

sub(2, 3) = -1, sub(3, 2) = 1. Порядок имеет значение

Именованные аргументы

Именованные аргументы сопоставляются с параметрами по их имени.

Пример передачи двух именованных аргументов

a = div(divident=4, divisor=2)

Предположим, функция div() делит divident (делимое) на divisor (делитель). Порядок в котом передаются именованные аргументы не важен, значения будут присвоены по совпадении имён.

Способ, которым передаётся определённый аргумент, определяется при вызове функции.

Один и тот же аргумент может быть передан как позиционный и как именованный.

def main(): print(div()) print(div(9, 3)) print(div(divisor=5, divident=25)) def div(divident=2, divisor=1): return divident/divisor if __name__ == "__main__": main()

2.0 3.0 5.0

Сперва нужно передавать позиционные аргументы, затем именованные

# Вызов print(div(divisor=5, 25)) # Приведёт к ошибке

print(div(divisor=5, 25)) ^ SyntaxError: positional argument follows keyword argument

Ещё один пример здесь

Про передачу заранее неопределёного количества аргументов читайте статью *args **kwargs

Аргументы по умолчанию

Аргументы, у которых есть значения по умолчанию, должны быть переданы после аргументов, у которых их нет.

# Arguments with default values must come # after those without default values. def banner(message, border="-"): line = border * len(message) print(line) print(message) print(line) banner("www.HeiHei.ru") # will use default "-" banner("www.TopBicycle.ru", "*") banner("www.KickBrains.ru", border="|")

python default_argumet_values.py

------------- www.HeiHei.ru ------------- ***************** www.TopBicycle.ru ***************** ||||||||||||||||| www.KickBrains.ru |||||||||||||||||

Значения по умолчанию

В качестве значений по умолчанию лучше использовать неизменяемые (immutable) объекты.

Если и использовать изменяемые объекты, то нужно понимать, что они получают значения один раз - когда интерпретатор проходит объявление функции (def)

Пример

import time print("time.ctime()", time.ctime()) def show_default(arg=time.ctime()): print(arg) show_default() time.sleep(2) print("time.ctime()", time.ctime()) show_default()

time.ctime() Wed Jun 8 11:16:04 2022 Wed Jun 8 11:16:04 2022 time.ctime() Wed Jun 8 11:16:06 2022 Wed Jun 8 11:16:04 2022

Как видно из вывода в терминал - время уже ушло вперёд - 11:16:06 а функция как возвращала значение по умолчанию созданное в 11:16:04 так и продолжает это делать.

Рассмотрим ещё один пример. Теперь в качестве изменяемого объекта возьмём список

def add_spam(menu=[]): menu.append("spam") return menu breakfast = ['bacon', 'eggs'] print(add_spam(breakfast)) lunch = ['borsh'] print(add_spam(lunch)) print(add_spam()) print(add_spam()) print(add_spam())

['bacon', 'eggs', 'spam'] ['borsh', 'spam'] ['spam'] ['spam', 'spam'] ['spam', 'spam', 'spam']

В первых двух случаях (завтрак и обед) функция работает как задумано. Но, если вызвать её без аргументов создасться пустой список и он не будет пересоздан - в него просто добавляются новые и новые элементы.

Решить эту проблему можно сделав аргумент по умолчанию неизменяемым

def add_spam(menu=None): if menu is None: menu = [] menu.append("spam") return menu breakfast = ['bacon', 'eggs'] print(add_spam(breakfast)) lunch = ['borsh'] print(add_spam(lunch)) print(add_spam()) print(add_spam()) print(add_spam())

['bacon', 'eggs', 'spam'] ['borsh', 'spam'] ['spam'] ['spam'] ['spam']

return

Рассмотрим скрипт test_return.py

def test_return(): return "A" v = test_return() print(v)

python test_return.py

A

Всё выглядит хорошо, функция вернула строку, мы видим её в терминале.

Но что будет, если эту функцию импортировать, а не вызвать в том же скрипте

tree return_ex

return_ex ├── parent_test_return.py └── test_return.py 0 directories, 2 files

# test_return def test_return(): return "A"

# parent_test_return from test_return import test_return v = test_return() print(v)

python parent_test_return.py

A

Области видимости

Рассмотрим четыре стандартные области видимости

Local: Внутри текущей функции
Enclosing: Внутри функции, вызывающей текущую
Global: Внутри модуля
Built-in: Встроенные в Python функции

Эта четвёрка описывается акронимом LEGB

Области видимости не имеют прямой связи с блоками кода.

Например, цикл for, хотя и нуждется в дополнительном отступе, не вводит новых областей видимости.

count = 0 def show_count(): print(count) def set_count(c): count = c show_count() # 0 set_count(5) show_count() # 0

0 0

count = 0 def set_count(c): global count count = c show_count() # 0 set_count(5) show_count() # 0

0 5

Продолжить изучение областей видимости функции можно в статье о локальных функциях замыкания: области видимости

Вызываемые объекты

Рассмотрим файл callables.py

def is_even(x): return x % 2 == 0 print(callable(is_even)) # True is_odd = lambda x: x % 2 == 1 print(callable(is_odd)) # True # Classes are callable print(callable(list)) # True # Methods are callable print(callable(list.append)) # True class CallMe: def __call__(self): print("Called!") my_call_me = CallMe() print(callable(my_call_me)) # True # Strings are not callable print(callable("This is no callable")) # False

python callables.py

True True True True True False

from functools import reduce import operator print(operator.add(8, 9)) print(reduce(operator.add, [1, 2, 3, 4, 5])) numbers = [1, 2, 3, 4, 5] accumulator = operator.add(numbers[0], numbers[1]) for item in numbers[2:]: accumulator = operator.add(accumulator, item) print(accumulator) def mul(x, y): print(f"mul {x} {y}") return x * y print(reduce(mul, range(1, 10))) # reduce(mul, []) # TypeErr reduce(mul, [1]) # returns element without calling reduce print(reduce(mul, [1])) # 1 # Initial value is added as a first accumulated value values = [1, 2, 3]

17 15 15 mul 1 2 mul 2 3 mul 6 4 mul 24 5 mul 120 6 mul 720 7 mul 5040 8 mul 40320 9 362880 1 6 0 6

Встроенные функции и теория

Функции
all()
any()
filter()
map()
ord()
sorted()
zip()
Похожие статьи
*args **kwargs
Лямбда функции
all()
any()
map()
zip()
ord()
sorted()
Функции первого класса
Замыкания
Декораторы
Кэширование
Python
if, elif, else
Циклы
Методы
enum

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

IT

Образование

Актуально сейчас

Разное

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящуюю по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: