Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Callable-объект в Python
Callable (вызываемый объект) — это любой объект, который можно вызвать как функцию с помощью скобок (). Callable-объекты — фундаментальная концепция Python для функционального программирования и создания гибких API.
Что такое callable?
Callable — это объект, который имеет метод __call__(). Когда ты вызываешь объект с (), Python автоматически вызывает его метод __call__:
# Проверка, является ли объект callable
callable(print) # True (функция)
callable(int) # True (класс)
callable("hello") # False (строка не callable)
callable(42) # False (число не callable)
from typing import Callable
# Тип для аннотации callable объектов
def apply_function(f: Callable[[int], int], x: int) -> int:
return f(x)
Примеры callable-объектов
1. Функции (обычные функции)
def greet(name):
return f"Hello, {name}!"
print(callable(greet)) # True
result = greet("Alice") # Вызов функции
print(result) # Hello, Alice!
2. Классы (классы тоже callable)
class Person:
def __init__(self, name):
self.name = name
print(callable(Person)) # True (класс callable)
person = Person("Alice") # Вызов класса создаёт объект
print(person.name) # Alice
3. Методы и bound methods
class Calculator:
def add(self, a, b):
return a + b
calc = Calculator()
print(callable(calc.add)) # True (метод callable)
result = calc.add(5, 3) # Вызов метода
print(result) # 8
4. Встроенные функции и объекты
print(callable(print)) # True
print(callable(len)) # True
print(callable(int)) # True
print(callable(sorted)) # True
print(callable(map)) # True
Создание собственного callable-объекта
Метод 1: Класс с __call__() методом
Это основной способ создать callable-объект:
class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, x):
return x * self.factor
triple = Multiplier(3)
print(callable(triple)) # True
print(triple(5)) # 15 (вызов __call__)
print(triple(10)) # 30
Практический пример: Кэширование
class Memoize:
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
if args not in self.cache:
self.cache[args] = self.func(*args)
return self.cache[args]
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
fib_cached = Memoize(fibonacci)
print(fib_cached(10)) # Первый вызов — медленный
print(fib_cached(10)) # Второй вызов — из кэша
Практический пример: Валидатор
class Validator:
def __init__(self, min_value=None, max_value=None):
self.min_value = min_value
self.max_value = max_value
def __call__(self, value):
if self.min_value is not None and value < self.min_value:
raise ValueError(f"Value too small")
if self.max_value is not None and value > self.max_value:
raise ValueError(f"Value too large")
return True
validate_age = Validator(min_value=0, max_value=150)
validate_age(25) # OK
Практический пример: Rate Limiter
import time
from collections import defaultdict
class RateLimiter:
def __init__(self, max_calls, time_window):
self.max_calls = max_calls
self.time_window = time_window
self.calls = defaultdict(list)
def __call__(self, user_id):
now = time.time()
self.calls[user_id] = [
t for t in self.calls[user_id]
if now - t < self.time_window
]
if len(self.calls[user_id]) >= self.max_calls:
raise Exception(f"Rate limit exceeded")
self.calls[user_id].append(now)
limit = RateLimiter(max_calls=5, time_window=60)
for i in range(5):
limit("user_123") # OK
Callable с параметрами
class Formatter:
def __init__(self, prefix="", suffix=""):
self.prefix = prefix
self.suffix = suffix
def __call__(self, text):
return f"{self.prefix}{text}{self.suffix}"
brackets = Formatter("[", "]")
quotes = Formatter('\"', '\"')
stars = Formatter("*** ", " ***")
print(brackets("Hello")) # [Hello]
print(quotes("World")) # \"World\"
print(stars("Important")) # *** Important ***
Callable в функциональном программировании
from functools import reduce
from typing import Callable, TypeVar
T = TypeVar('T')
def pipe(*functions: Callable) -> Callable:
def composed(value):
return reduce(lambda v, f: f(v), functions, value)
return composed
add_tax = lambda price: price * 1.2
apply_discount = lambda price: price * 0.9
round_price = lambda price: round(price, 2)
calculate_final_price = pipe(add_tax, apply_discount, round_price)
original_price = 100
final_price = calculate_final_price(original_price)
print(final_price) # 108.0
Проверка callable
# Функция callable()
print(callable(print)) # True
print(callable(lambda x: x)) # True
print(callable("string")) # False
# Используется в type hints
from typing import Callable
def execute_function(func: Callable[[int], int], value: int) -> int:
return func(value)
execute_function(lambda x: x * 2, 5) # OK
Резюме
Callable-объект — это любой объект с методом __call__(), который можно вызвать как функцию:
- Встроенные callable'ы: функции, классы, методы, встроенные функции
- Пользовательские callable'ы: классы с методом
__call__() - Преимущества: инкапсуляция состояния, многократное использование, декоратор паттерны
- Примеры: кэширование, валидация, rate limiting, форматирование
Callable-объекты — мощный инструмент для создания функционального и гибкого кода в Python.