- Расширенное использование функций - «первоклассные граждане» / функции высшего порядка / лямбда-функции / области видимости и замыкания / декораторы
В Python функции могут быть использованы для решения широкого спектра задач и проблем. Вот несколько расширенных сценариев использования функций:
-
Рекурсивные функции - функции, которые вызывают сами себя. Это особенно полезно в алгоритмах, которые подразумевают глубокую вложенность.
-
Функции высшего порядка - это функции, которые принимают другие функции в качестве аргументов или возвращают их как результат. Это особенно полезно для функционального программирования.
-
Анонимные функции (лямбда-выражения) - это функции без имени, которые могут использоваться в качестве аргументов в других функциях для создания кратких и компактных выражений.
-
Генераторы - это функции, которые используются для создания итераторов в Python. Они позволяют создавать последовательности значений по требованию, вместо того, чтобы создавать целую последовательность сразу.
-
Декораторы - это функции, которые позволяют изменять поведение других функций. Декораторы могут использоваться для добавления дополнительной функциональности функциям без изменения их кода.
-
Модуль functools - это стандартный модуль Python, который содержит множество функций, которые могут использоваться для дополнительной обработки и изменения поведения функций в Python. Здесь можно найти функции, такие как functools.partial, которые позволяют создавать новые функции на основе существующих, и functools. lru_cache, который позволяет кэшировать результаты выполнения функции для повышения ее производительности.
Python - объектно-ориентированный язык программирования, в котором функции - это "граждане первого класса". Это означает, что функции в Python имеют множество свойств классических объектов, таких как возможность передачи как параметров, возвращение в качестве результата, сохранение в переменных и передача другим функциям.
Это является очень мощным инструментом, позволяющим создавать сложные программы и сокращать объем кода благодаря возможности переиспользования кода внутри программы.
Ниже приведены некоторые примеры использования функций в Python:
- Простая функция для вычисления квадрата числа:
def square(x):
return x*x
result = square(5)
print(result) # Выведет 25- Функция, принимающая список чисел и возвращающая сумму всех чисел в списке:
def sum_numbers(numbers):
sum = 0
for num in numbers:
sum += num
return sum
result = sum_numbers([1, 2, 3, 4, 5])
print(result) # Выведет 15- Функция, использующая функцию в качестве параметра:
"""
Python 3.10 расширенные возможности функции
Название файла '01.калькулятор.py'
Version: 0.1
Author: Andrej Marinchenko
Date: 2023-05-03
"""
def calculator(operation, x, y):
if operation == "add":
return x+y
elif operation == "subtract":
return x-y
elif operation == "multiply":
return x*y
elif operation == "divide":
return x/y
def square(x):
return x*x
result = calculator("multiply", 5, 6)
print(result) # Выведет 30 = 5*6
print(square(5)) # Выведет 25 = 5*5
print(calculator(square, 5, 5)) # None
print(calculator("divide", square(10), 5)) # 20.0 =((10*10)/5)Функция «калькулятор» принимает одну из четырех операций и два числа в качестве параметров. Затем она использует переданную функцию в качестве операции и выполняет операцию между двумя числами.
- Анонимные функции:
square = lambda x: x*x
result = square(5)
print(result) # Выведет 25Анонимная функция - это функция без имени, которая может быть определена в одну строку кода. Они удобны, когда вам нужна небольшая функция, которую можно определить прямо на месте. В приведенном примере мы определяем функцию square, которая возвращает квадрат переданного числа.
В целом, использование функций как "граждан первого класса" в Python позволяет создавать более читабельный и переиспользуемый код. Их можно использовать для многих задач, таких как вычисление, обработка данных и многих других.
Высшие функции в Python - это функции, которые могут принимать одну или несколько функций в качестве аргументов и/или возвращать функции в качестве результата. Это очень мощная концепция, которую можно использовать для создания гибких и модульных программ.
Приведу несколько примеров высших функций в Python с описанием:
- map(function, iterable) - применяет функцию к каждому элементу итерируемого объекта (например, списка или кортежа) и возвращает новый итератор с результатами. Пример:
def square(x):
return x ** 2
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(square, numbers))
print(squared_numbers) # Output: [1, 4, 9, 16, 25]- filter(function, iterable) - возвращает новый итератор с элементами итерируемого объекта, для которых функция возвращает истинное значение. Пример:
# функция определения не четных чисел
def is_odd(x):
return x % 2 != 0 # возвращает число не кратное двум
numbers = [1, 2, 3, 4, 5]
odd_numbers = list(filter(is_odd, numbers))
print(odd_numbers) # Output: [1, 3, 5]- reduce(function, iterable[, initializer]) - применяет функцию к элементам итерируемого объекта, частично сводя его к одному значению. Пример:
from functools import reduce
def multiply(x, y):
return x * y
numbers = [1, 2, 3, 4, 5]
product = reduce(multiply, numbers)
print(product) # Output: 120- lambda arguments: expression - используется для создания анонимных функций. Пример:
square = lambda x: x ** 2
print(square(5)) # Output: 25- sorted(iterable, key=None, reverse=False) - сортирует элементы итерируемого объекта в порядке возрастания (или
убывания, если
reverse=True) и возвращает новый отсортированный список. Ключkeyопределяет функцию, которая будет использоваться для извлечения значения, по которому будет происходить сортировка. Пример:
names = ['Alice', 'Bob', 'Charlie', 'Dave']
sorted_names = sorted(names, key=len) # отсортирует список по длине каждого слова
print(sorted_names) # Output: ['Bob', 'Dave', 'Alice', 'Charlie']Это только несколько примеров высших функций в Python. Есть много других функций, которые могут быть использованы для задач, которые считаются более сложными, но эти пять функций должны дать вам представление о том, что высшие функции могут делать.
Лямбда-функции в Python - это анонимные функции, которые могут быть определены в одной строке. Они могут быть использованы везде, где требуется функция, но не требуется назначать ее имени. Вот несколько примеров лямбда-функций в Python:
'''Пример 1:'''
lambda x: x**2
# Эта лямбда-функция берет один аргумент x и возвращает квадрат этого аргумента.
'''Пример 2:'''
lambda x, y: x + y
# Эта лямбда-функция берет два аргумента, x и y, и возвращает их сумму.
'''Пример 3:'''
lambda x: True if x >= 0 else False
# Эта лямбда-функция берет один аргумент x и возвращает True, если x больше или равен нулю, и False в обратном случае.
'''Пример 4:'''
lambda x: x[0]
# Эта лямбда-функция берет один аргумент x, который является списком или кортежем, и возвращает первый элемент этого списка.
'''Пример 5:'''
(lambda x: x**2)(3)
# Этот пример показывает, как вызвать лямбда-функцию с аргументом. Здесь мы вызываем функцию, которая берет один
# аргумент x и возвращает его квадрат, передавая в нее значение 3. Результатом выполнения будет число 9. Это только несколько из возможных примеров использования лямбда-функций в Python. Они могут быть использованы в любом контексте, где необходима быстрая, одноразовая функция.
Область видимости определяет область, в которой переменная доступна и может быть использована. В Python есть две основные области видимости: глобальная и локальная.
Локальная область видимости ограничена функцией, в которой переменная была определена. Переменные, созданные внутри функции, не могут быть использованы за ее пределами.
Пример:
def my_function():
x = 10
print(x)
my_function() # результат: 10
print(x) # ошибка, переменная x не определена в глобальной области видимостиГлобальная область видимости доступна для всего кода, который находится в файле. Переменные, созданные в глобальной области видимости, могут быть использованы в любой другой функции или классе.
Пример:
x = 20
def my_function():
print(x)
my_function() # результат: 20
print(x) # результат: 20Замыкание функций это возможность сохранить переменные внутри функции, даже после ее завершения работы. Это позволяет сделать эти переменные доступными для использования в другом месте программы.
Пример:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
result = outer_function(10)
print(result(20)) # результат: 30Этот пример создает функцию outer_function, которая возвращает другую функцию inner_function. При вызове
outer_function(10) в переменной result сохраняется результат inner_function. Поэтому result(20) вызывает
inner_function(20) с результатом 30. Хотя x была определена в outer_function, она все еще доступна для
использования внутри inner_function благодаря замыканию функций.
Декораторы функций - это специальные функции, которые используются для обертки или изменения других функций без необходимости изменения их самостоятельно. Они позволяют добавлять дополнительную функциональность к функциям, не затрагивая ее исходного кода.
Примеры декораторов функций:
- @classmethod - это декоратор класса, который используется для создания методов класса.
Пример:
class MyClass:
count = 0
def __init__(self):
MyClass.count += 1
@classmethod
def get_count(cls):
return cls.count- @property - это декоратор, который позволяет превратить метод класса в свойство.
Пример:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def area(self):
return 3.14 * self._radius ** 2- @staticmethod - это декоратор, который объявляет метод класса как статический.
Пример:
class MyClass:
@staticmethod
def get_square(number):
return number ** 2В этом примере мы объявляем метод get_square() статическим, чтобы использовать его без необходимости создания экземпляра класса.
- @log - это декоратор, который добавляет логирование в функцию.
Пример:
import logging
logging.basicConfig(filename='logfile.txt',level=logging.DEBUG)
def log(func):
def wrapper(*args, **kwargs):
logging.debug(f"Executing function {func.__name__}")
result = func(*args, **kwargs)
logging.debug(f"Function {func.__name__} returned {result}")
return result
return wrapper
@log
def add(x, y):
return x + yВ этом примере мы создаем декоратор log(), который добавляет логирование для функции add(), чтобы мы могли отслеживать ее выполнение.
пример: декоратор времени выполнения выходной функции.
def record_time(func):
"""Декоратор для индивидуально оформленных функций"""
@wraps(func)
def wrapper(*args, **kwargs):
start = time()
result = func(*args, **kwargs)
print(f'{func.__name__}: {time() - start}秒')
return result
return wrapperВ этом примере мы создаем функцию которая предназначена для оценки времени выполнения другой функции, принимаемой на вход, на выходе этой функции мы получаем результат принимаемой на вход функции, а также ее время выполнения
Декоратор в Python - это функция, которая принимает в качестве аргументов другую функцию, выполняет некоторые действия и возвращает эту функцию. Параметризуемые декораторы в Python - это декораторы, которые могут принимать аргументы. Вот несколько примеров параметризуемых декораторов:
- Декоратор, который выполняет функцию указанное количество раз:
def repeat(num):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(num):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(num=3)
def hello(name):
print(f"Hello, {name}")
hello("Jack") # Hello, Jack
# Hello, Jack
# Hello, Jack- Декоратор, который замеряет время выполнения функции:
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
total_time = end_time - start_time
print(f"Execution time: {total_time}")
return result
return wrapper
@timer
def count():
num = 0
for i in range(1000000):
num += i
return num
count() # Execution time: 0.07399797439575195
# 499999500000- Декоратор, который выполняет функцию только если ее аргументы удовлетворяют условие:
def check_args(type):
def decorator(func):
def wrapper(*args, **kwargs):
for arg in args:
if type(arg) != type:
return f"Invalid argument type: {arg}"
for key, value in kwargs.items():
if type(value) != type:
return f"Invalid argument type: {key}"
return func(*args, **kwargs)
return wrapper
return decorator
@check_args(int)
def sum(x, y):
return x + y
print(sum(1, 2)) # 3
print(sum("a", "b")) # Invalid argument type: a
print(sum(1, "b")) # Invalid argument type: bЭти примеры помогут вам понять, как можно использовать параметризуемые декораторы в Python.
Рекурсивная функция - это функция, которая вызывает саму себя. Зачастую использование рекурсии в программировании позволяет более лаконично и элегантно описывать сложные задачи.
Пример 1:
Функция, которая вычисляет факториал числа. Факториал числа n обозначается через n! и равен произведению всех натуральных чисел от 1 до n включительно:
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)В этой функции сначала проверяется, не является ли n равным 1. Если это так, то возвращается 1 (факториал числа 1 равен 1). Если же n не равно 1, то функция возвращает произведение числа n на результат вызова функции с аргументом n-1. Таким образом, функция вызывает саму себя, пока не достигнет базового случая (n=1).
Пример 2:
Функция, которая вычисляет числа Фибоначчи. Числа Фибоначчи определяются следующей последовательностью: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... Каждый следующий элемент равен сумме двух предыдущих элементов.
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)В этой функции сначала проверяется, не является ли n равным 0 или 1. Если это так, то возвращается соответствующий элемент последовательности. Если же n больше 1, то функция возвращает сумму результатов вызовов функции с аргументами n-1 и n-2. Таким образом, функция вызывает саму себя, пока не достигнет базовых случаев (n=0 или n=1).
Примеры:
- 01.калькулятор.py
- 02.рекурсивная_функция.py
- 03.область_действия.py