← Назад к вопросам

Что такое callable-объект?

2.0 Middle🔥 131 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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__(), который можно вызвать как функцию:

  1. Встроенные callable'ы: функции, классы, методы, встроенные функции
  2. Пользовательские callable'ы: классы с методом __call__()
  3. Преимущества: инкапсуляция состояния, многократное использование, декоратор паттерны
  4. Примеры: кэширование, валидация, rate limiting, форматирование

Callable-объекты — мощный инструмент для создания функционального и гибкого кода в Python.

Что такое callable-объект? | PrepBro