[PYTHON] A note about __call__

Introduction

Both python and keras are beginners. It is a memorandum for myself.

What is this way of writing

The Keras functional API allows you to use more complex neural networks than the keras Sequential API.

That's where the following writing style comes out.

001.py


import keras
from keras import layers

inputs = layers.Input(shape=(784,))
dense_hoge = layers.Dense(64, activation='relu')
x = dense_hoge(inputs)#this!

dense_hoge is an instance of the keras.layers.core.Dense class, but the instance name is followed by parentheses, and the variable name inputs is written inside.

Moreover, the last two lines are

002.py


x = layers.Dense(64, activation='relu')(inputs)

You can also write. I've never seen the way variable name 1 (variable name 2) is written.

What the hell is this doing and how?

Result of investigation

It was said that the \ _ \ _ call \ _ \ _ function defined in the class is processing.

Let's write a simple class.

003.py


class A:
    def __init__(self):
        print("ClassA __init__")
    
    def __call__(self):
        print ("ClassA __call__")

Create a class A object and store it in a.

003.py


a = A()
#ClassA __init__

Try calling instance a with ().

003.py


a()
#ClassA __call__

So, I found that if you add () to the instance name, the process defined by \ _ \ _ call \ _ \ _ will be executed.

What about classes where \ _ \ _ call \ _ \ _ is not defined?

004.py


class B:
    def __init__(self):
        print("ClassB __init__")

b = B()
#ClassB __init__
b()  #I get the following error
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: 'B' object is not callable

The'B'object was displayed as not callable. It is said that callable () can be used to check if it is callable, so I tried it.

004.py


callable(a)
#True
callable(b)
#False

Class B that does not define \ _ \ _ call \ _ \ _ is now False.

Specifying a class instead of an instance resulted in true for both Class A and Class B.

005.py


callable(A)
#True
callable(B)
#True

Can you call them continuously?

\ _ \ _ Call \ _ \ _ was that the object could be the return value. So, if \ _ \ _ call \ _ \ _ returns a callable object, can we call the next \ _ \ _ call \ _ \ _ in succession? The following Class C returns an instance of Class A. An instance of Class A is callable, and calling \ _ \ _ call \ _ \ _ should return Class A \ _ \ _ call \ _ \ _.

006.py


class C:
    def __init__(self):
        print("ClassC __init__")
    
    def __call__(self):
        print ("ClassC __call__")
        return A()

c = C()
c()()
#ClassC __call__   
#ClassA __init__    #of class C__call__Output when instantiating Class A with
#ClassA __call__

.... I was able to call in succession. I don't think you should use it too much as the code will be confusing, but I found it to work continuously.

What happens if I use an existing function name as the variable name?

I found that I could write the variable name (). In python, even a character string used as a function name could be used as a variable name. For example, the variable name is print. If print () is used, will it be called \ _ \ _ call \ _ \ _? Or is it a normal print function?

007.py


print = A()
print('123') #The following error display
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: __call__() takes 1 positional argument but 2 were given

\ _ \ _ Call \ _ \ _ was called.

Consideration

I found that I could write the variable name ().

What is the difference between defining and using \ _ \ _ call \ _ \ _ in a class and defining and using the function hoge ()? What is the difference between a variable name (argument) and a variable name.hoge (argument)?

As a disadvantage of how to write a variable (),

  1. Until now, it was decided that the function name was in front of the parentheses, but this is not always the case. Reduces the readability of the code.
  2. If you unknowingly use the same variable name as an existing function name, that function cannot be used.

There are two possible points. Is there any merit in using \ _ \ _ call \ _ \ _?

Methods like \ _ \ _ call \ _ \ _ seem to be called special methods. It seems that it can be used in various ways, but it seems that there are many explanation pages, so I would like to end here.

Recommended Posts

A note about __call__
A note about subprocess
A note about mprotect (2)
A note about KornShell (ksh)
A note about TensorFlow Introduction
A note about [python] __debug__
A note about get_scorer in sklearn
A note about mock (Python mock library)
Note about awk
Just a note
A note about doing the Pyramid tutorial
A memorandum about matplotlib
Note about pointers (Go)
A memorandum about Nan.
A note about the python version of python virtualenv
Data analysis in Python: A note about line_profiler
A note about the new style base class
A note about checking modifiers with Max Plus
How to call a function
What is a system call
A memorandum about Python mock
A little more about FIFO
A small note following printf
A note about hitting the Facebook API with the Python SDK
Call a Python function from p5.js.
Note
A refreshing story about Python's Slice
A note when gcloud is broken
A sloppy story about Python's Slice
I have a question about whitespace
Note
A small sample note of list_head
a () and a.__ call__ () are not equivalent
A note about connecting Spark to OpenStack Swift-based IBM Object Storage
Python-dynamically call a function from a string
A note for writing Python-like code
A note that prints numpy.array nicely
A story about using Python's reduce
[Translation] A note about structured concurrency .. or rather go statements seem harmful
A note about the functions of the Linux standard library that handles time
A note where a Python beginner got stuck
[Note] Read a file from another directory
A story about remodeling Lubuntu into a Chromebook
I touched "Orator" so I made a note
A Java programmer studied Python. (About type)
A memorandum of understanding about django's QueryDict
A note on enabling PostgreSQL with Django
A story about Python pop and append
Memo about Sphinx Part 1 (Creating a project)
Call a command from Python (Windows version)
A story about a 503 error on Heroku open
About February 02, 2020 * This is a Python article.
[Note] A story about not being able to break through a proxy with pip