[PYTHON] Une note sur __call__

introduction

Les deux python et keras sont des débutants. C'est un mémorandum pour moi.

Quelle est cette façon d'écrire

L'API fonctionnelle Keras vous permet d'utiliser des réseaux de neurones plus complexes que l'API séquentielle keras.

C'est là que le style d'écriture suivant ressort.

001.py


import keras
from keras import layers

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

dense_hoge est une instance de la classe keras.layers.core.Dense, mais le nom de l'instance est suivi de parenthèses et le nom de la variable inputs est écrit à l'intérieur.

De plus, les deux dernières lignes sont

002.py


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

Vous pouvez également écrire. Je n'ai jamais vu comment écrire le nom de variable 1 (nom de variable 2).

Qu'est-ce que ça fait et comment?

Résultat de l'enquête

Il a été dit que la fonction \ _ \ _ call \ _ \ _ définie dans la classe est en cours de traitement.

Écrivons une classe simple.

003.py


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

Créez un objet de classe A et stockez-le dans un fichier.

003.py


a = A()
#ClassA __init__

Essayez d'appeler l'instance a avec ().

003.py


a()
#ClassA __call__

Donc, j'ai trouvé que l'ajout de () au nom de l'instance exécute le processus défini dans \ _ \ _ call \ _ \ _.

Qu'en est-il des classes où \ _ \ _ call \ _ \ _ n'est pas défini?

004.py


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

b = B()
#ClassB __init__
b()  #J'obtiens l'erreur suivante
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: 'B' object is not callable

L'objet'B'a été affiché comme non appelable. On dit que callable () peut être utilisé pour vérifier s'il est appelable, alors je l'ai essayé.

004.py


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

La classe B qui ne définit pas \ _ \ _call \ _ \ _ est désormais False.

Spécifier une classe au lieu d'une instance a donné la valeur true pour les classes A et B.

005.py


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

Pouvez-vous les appeler en permanence?

\ _ \ _ Call \ _ \ _ était que l'objet pouvait être la valeur de retour. Donc, si \ _ \ _ call \ _ \ _ renvoie un objet appelable, pouvons-nous appeler le prochain \ _ \ _ appel \ _ \ _ successivement? La classe C suivante renvoie une instance de la classe A. Une instance de la classe A peut être appelée et l'appel de \ _ \ _ call \ _ \ _ doit renvoyer la classe 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__    #de classe C__call__Sortie lorsque la classe A est instanciée dans
#ClassA __call__

.... J'ai pu appeler successivement. Je ne pense pas qu'il devrait être beaucoup utilisé car le code sera déroutant, mais j'ai trouvé qu'il fonctionnait en permanence.

Que se passe-t-il si j'utilise un nom de fonction existant comme nom de variable?

J'ai trouvé que je pouvais écrire le nom de la variable (). En python, même la chaîne de caractères utilisée comme nom de fonction peut être utilisée comme nom de variable. Par exemple, le nom de la variable est print. Si print () est utilisé, sera-t-il appelé \ _ \ _ call \ _ \ _? Ou est-ce une fonction d'impression normale?

007.py


print = A()
print('123') #L'affichage d'erreur suivant
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: __call__() takes 1 positional argument but 2 were given

\ _ \ _ L'appel \ _ \ _ a été appelé.

Considération

J'ai trouvé que je pouvais écrire le nom de la variable ().

Quelle est la différence entre définir et utiliser \ _ \ _ call \ _ \ _ dans une classe et définir et utiliser la fonction hoge ()? Quelle est la différence entre un nom de variable (argument) et un nom de variable.hoge (argument)?

En tant qu'inconvénient de la façon d'écrire la variable ()

  1. Jusqu'à présent, il était décidé que le nom de la fonction était devant les parenthèses, mais ce n'est pas toujours le cas. Réduit la lisibilité du code.
  2. Si vous utilisez sans le savoir le même nom de variable qu'un nom de fonction existant, cette fonction ne peut pas être utilisée.

Il y a deux points possibles. Y a-t-il intérêt à utiliser \ _ \ _ call \ _ \ _?

Les méthodes comme \ _ \ _ call \ _ \ _ semblent être appelées méthodes spéciales. Il semble qu'il puisse être utilisé de différentes manières, mais il semble qu'il y ait de nombreuses pages d'explications, alors je voudrais terminer ici.

Recommended Posts

Une note sur __call__
Une note sur le sous-processus
Une note sur mprotect (2)
Une note sur KornShell (ksh)
Une note sur TensorFlow Introduction
Une note sur [python] __debug__
Remarque à propos de get_scorer de sklearn
Une note sur mock (bibliothèque fictive Python)
Remarque sur awk
Juste une note
Un mémo que j'ai essayé le tutoriel Pyramid
Remarque sur les pointeurs (Go)
Un mémorandum sur Nan.
Écrire une note sur la version python de python virtualenv
Analyse de données en Python: une note sur line_profiler
Une note sur la nouvelle classe de base de style
Modificateurs de vérification des mémos avec MaxPlus
Comment appeler une fonction
Qu'est-ce qu'un appel système
Un mémorandum sur le simulacre de Python
Un peu plus sur le FIFO
Une petite note qui suit printf
Une note sur l'utilisation de l'API Facebook avec le SDK Python
Note
Une histoire rafraîchissante sur Slice en Python
Remarques lorsque gcloud est cassé
Une histoire de mauvaise humeur sur Slice en Python
J'ai une question sur les blancs
Note
Un petit exemple de note de list_head
a () et a .__ call__ () ne sont pas équivalents
Remarque sur la connexion de Spark à IBM Object Storage basé sur OpenStack Swift
Python --Fonction d'appel dynamique à partir d'une chaîne
Notes pour écrire du code de type Python
Une note qui imprime joliment numpy.array
L'histoire de l'utilisation de la réduction de Python
[Français] Une note sur le traitement parallèle structuré. Ou plutôt, la déclaration go semble être nuisible
Une note sur les fonctions de la bibliothèque Linux standard qui gère le temps
Une note où un débutant Python s'est retrouvé coincé
[Note] Lire un fichier depuis un autre répertoire
Une histoire sur un remodelage magique qui met Lubuntu dans un Chromebook
J'ai touché "Orator" alors j'ai fait une note
Un programmeur Java a étudié Python. (À propos du type)
Mémorandum sur le QueryDict de Django
Remarques sur l'activation de PostgreSQL avec Django
Une histoire sur Python pop and append
Mémo sur Sphinx Partie 1 (Création d'un projet)
Appeler des commandes depuis Python (édition Windows)
À propos du 02 février 2020 * Ceci est un article Python.
[Note] Une histoire sur l'impossibilité de percer le proxy avec pip