Python __call__ специальный метод практический пример - PullRequest
147 голосов
/ 29 апреля 2011

Я знаю, что __call__ метод в классе запускается, когда вызывается экземпляр класса. Однако я понятия не имею, когда я смогу использовать этот специальный метод, поскольку можно просто создать новый метод и выполнить ту же операцию, что и в методе __call__, и вместо вызова экземпляра вы можете вызвать метод.

Я был бы очень признателен, если бы кто-нибудь дал мне практическое применение этого специального метода.

Ответы [ 13 ]

0 голосов
/ 27 января 2019

Я нахожу хорошее место для использования вызываемых объектов, которые определяют __call__(), когда используются функциональные возможности программирования в Python, такие как map(), filter(), reduce().

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

Вот некоторый код, который фильтрует имена файлов по их расширению, используя вызываемый объект и filter().

Callable:

import os

class FileAcceptor(object):
    def __init__(self, accepted_extensions):
        self.accepted_extensions = accepted_extensions

    def __call__(self, filename):
        base, ext = os.path.splitext(filename)
        return ext in self.accepted_extensions

class ImageFileAcceptor(FileAcceptor):
    def __init__(self):
        image_extensions = ('.jpg', '.jpeg', '.gif', '.bmp')
        super(ImageFileAcceptor, self).__init__(image_extensions)

Использование:

filenames = [
    'me.jpg',
    'me.txt',
    'friend1.jpg',
    'friend2.bmp',
    'you.jpeg',
    'you.xml']

acceptor = ImageFileAcceptor()
image_filenames = filter(acceptor, filenames)
print image_filenames

Выход:

['me.jpg', 'friend1.jpg', 'friend2.bmp', 'you.jpeg']
0 голосов
/ 12 сентября 2018

Оператор вызова функции. </p> <pre><code>class Foo: def __call__(self, a, b, c): # do something x = Foo() x(1, 2, 3)

Метод __ call __ может использоваться для переопределения / повторной инициализации того же объекта. Это также облегчает использование экземпляров / объектов класса в качестве функций путем передачи аргументов объектам.

0 голосов
/ 24 февраля 2018

Один общий пример - __call__ в functools.partial, здесь приведена упрощенная версия (с Python> = 3,5):

class partial:
    """New function with partial application of the given arguments and keywords."""

    def __new__(cls, func, *args, **kwargs):
        if not callable(func):
            raise TypeError("the first argument must be callable")
        self = super().__new__(cls)

        self.func = func
        self.args = args
        self.kwargs = kwargs
        return self

    def __call__(self, *args, **kwargs):
        return self.func(*self.args, *args, **self.kwargs, **kwargs)

Использование:

def add(x, y):
    return x + y

inc = partial(add, y=1)
print(inc(41))  # 42
...