[Road to Python Intermediate] Call a class instance like a function with __call__

Link to summary

https://qiita.com/ganariya/items/fb3f38c2f4a35d1ee2e8

Introduction

In order to study Python, I copied a swarm intelligence library called acopy.

In acopy, many interesting Python grammars and idioms are used, and it is summarized that it is convenient among them.

This time, let's look at the __call__ attribute that calls an instance of a class like a function.

__call__ attribute method

If you define the __call__ attribute in a class, You can call an instance like a function with the () operator.

class Person:

    def __init__(self, age, name):
        self.age = age
        self.name = name

    def __repr__(self):
        return f'age = {self.age}, name = {self.name}'

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


'''
age = 20, name = ron
ron
'''
p = Person(20, 'ron')
print(p)
print(p())

In the above example, the __call__ attribute is defined in the Person class. This will return the name of p when the instance is called, like a function call.

In this way, it is __call__ that allows you to call it like a function.

Usage example

So how happy is it with this ()?

Simple interface

I don't think it should be done much, but as a simple interface I wonder if it can be used.

class Add:

    def __init__(self, x):
        self.x = x

    def __call__(self, y):
        return self.x + y


class Sub:

    def __init__(self, x):
        self.x = x

    def __call__(self, y):
        return self.x - y


'''
20
10
50
'''
arr = [Add(10), Sub(20), Add(40)]
for ice in arr:
    print(ice(10))

I think it's something different.

Give the function a state

I think this is mainly the meaning of this. In C ++, there is a function object that has () in the struct. This is my article that touched on it. (There is no reason why my unordered_map can't use pair type as a key)

It's hard to give a function a state, but a class can easily have a state. Then, it is possible to get the number of times the () operator is used and the calculation result such as DP of heavy processing.

class Count:
    cls_count = 0

    def __init__(self):
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        Count.cls_count += 1
        return self.count, Count.cls_count


c1 = Count()
c2 = Count()

'''
(1, 1)
(1, 2)
(2, 3)
(3, 4)
(2, 5)
'''
print(c1())
print(c2())
print(c1())
print(c1())
print(c2())

In the above code, we create a Count class and call it as a function. Internally, the variables and internal states cls_count, count are saved.

The above is a good example, but you can save the internal state in a function call called ().

Also, the following is a function call to the Eratosthenes sieve. After calculating once, the internally cached value is returned.

class Era:

    def __init__(self, N):
        self.N = N
        self.primes = []
        self.ready = False

    def __call__(self, x):
        if self.ready:
            return self.primes[x]
        else:
            self.primes = [True] * (self.N + 1)
            self.primes[0] = self.primes[1] = False

            i = 2
            while i * i <= self.N:
                if self.primes[i]:
                    for j in range(i * 2, N + 1, i):
                        self.primes[j] = False
                i += 1
            return self.primes[x]


N = 100
era = Era(N)

for i in range(0, N + 1):
    print(i, era(i))

In this way, I want to call it like a function with () from the outside, but when I want to have an internal state, it seems good to use __call__.

References

-About the call method -A story I didn't understand call and callable

Recommended Posts

[Road to Python Intermediate] Call a class instance like a function with __call__
A road to intermediate Python
[Road to Python Intermediate] Define __getattr__ function in class
Create a Python function decorator with Class
How to call a function
[Road to intermediate Python] Define in in your own class
[Python] How to call a c function from python (ctypes)
[Python] Road to a snake charmer (5) Play with Matplotlib
[Road to intermediate Python] Install packages in bulk with pip
Create a Mastodon bot with a function to automatically reply with Python
How to use the __call__ method in a Python class
[Road to intermediate Python] Enables comparison operations with original classes
Call a Python function from p5.js.
How to write a Python class
[Python] Road to snake charmer (3) Python class
[Python] Inherit a class with class variables
[Road to Intermediate] Understanding Python Properties
[Introduction to Python] How to split a character string with the split function
[Python 3.8 ~] How to define a recursive function smartly with a lambda expression
Let's feel like a material researcher with python [Introduction to pymatgen]
[Road to intermediate Python] Use ternary operators
Build a blockchain with Python ① Create a class
[Python] How to make a class iterable
[Road to intermediate Python] Use lambda expressions
The road to compiling to Python 3 with Thrift
[Road to intermediate Python] Article link summary
[Python] Explains how to use the range function with a concrete example
Hit a method of a class instance with the Python Bottle Web API
[Introduction to Python] How to write a character string with the format function
Python class, instance
How to read a CSV file with Python 2/3
Send a message to LINE with Python (LINE Notify)
[Python] Road to a snake charmer (4) Tweak Numpy
To execute a Python enumerate function in JavaScript
[Python] Road to a snake charmer (6) Manipulate Pandas
Try to draw a life curve with python
I want to make a game with Python
[Note] Create a one-line timezone class with python
Try to make a "cryptanalysis" cipher with Python
[Road to Intermediate] Python seems to be all objects
Python: Prepare a serializer for the class instance:
Decide to assign a laboratory with Python (fiction)
Steps to create a Twitter bot with python
Try to make a dihedral group with Python
[Go] How to write or call a function
I want to write to a file with Python
A layman wants to get started with Python
[Python] Created a class to play sin waves in the background with pyaudio
How to convert / restore a string with [] in python
[Python] How to draw a line graph with Matplotlib
Try to make a command standby tool with python
[Introduction to Python] How to iterate with the range function?
Python Ver. To introduce WebPay with a little code.
I tried to draw a route map with Python
[Practice] Make a Watson app with Python! # 2 [Translation function]
How to convert a class object to a dictionary with SQLAlchemy
Forcibly draw something like a flowchart with Python, matplotlib
Make a function to describe Japanese fonts with OpenCV
I want to work with a robot in python.
From buying a computer to running a program with python
I tried to automatically generate a password with Python3