[Python] Comment forcer une méthode d'une sous-classe à effectuer un processus spécifique

Je veux forcer un processus spécifique sur une sous-classe

Lors de la conception d'une sous-classe qui hérite d'une certaine classe en Python, vous souhaitez parfois que la destination héritée effectue ce type de traitement.

Par exemple, je veux que vous appeliez super () .__ init __ () chaque fois que __init __ est appelé ...

Non limité à __init__, le processus de" Je veux remplacer la méthode de la classe parente, mais je veux appeler la méthode de la classe parente telle quelle! "Apparaît souvent, mais j'ai oublié d'écrire le processus d'appel de la méthode de la classe parente. Je ne veux pas faire d'erreur, et la spécification elle-même qui appelle la méthode de la classe parent est gênante en premier lieu.

Cette fois, lorsque la méthode f de la classe enfant sera appelée, nous essaierons d'implémenter une implémentation dans laquelle la méthode f de la classe parent est toujours appelée après le traitement.

manière

** Réécrire "fonction de classe enfant f" en "fonction new_f qui exécute la fonction de classe enfant f et la fonction de classe parent f" ** Ecrire une méta classe qui fait ça

Qu'est-ce qu'une méta-classe? L'histoire sera différente cette fois. Pour le moment, pensez-y comme une classe qui modifie la façon dont les classes sont définies.

Je crois que même les personnes qui ne le connaissent pas peuvent tout faire en copiant et collant le code ci-dessous et en réécrivant la méthode decorate.

supposition

Python: 3.7.2 (Peut-être OK pour Python3, seule la méthode de spécification de la métaclasse est différente pour Python2)

code

class ParentCaller(type):
    def __new__(cls, name, base, attr):
        #Empêcher f dans la classe Parent d'appeler f dans la classe Parent
        if name != "Parent":
            #Rendre la fonction f automatiquement décorée lors de la création de la classe
            attr["f"] = cls.decorate(attr["f"])
        return super().__new__(cls, name, base, attr)

    @classmethod
    def decorate(cls, f):
        #Lorsque la fonction f est reçue, f et Parent.Exécuter f comme un nouvel ensemble_Renvoie f
        def new_f(self, x):
            f(self, x)
            Parent.f(self, x)
        return new_f


class Parent(metaclass=ParentCaller):
    def f(self, x):
        print(f"parent's f says: {x}")


class Child(Parent):
    def f(self, x):
        print(f"child's f says: {x}")


child = Child()
child.f("Hello World!")

#  child's f says: Hello World!
#  parent's f says: Hello World!

Résumé

Lorsque vous écrivez une bibliothèque comme Tensorflow dont les gens héritent et utilisent, je veux éviter autant que possible la promesse de "Run hogehoge here!". Dans un tel cas, écrivez une méta-classe et appelez hogehoge à votre insu.

Il semble que la méta-programmation soit difficile à lire et détestée dans le développement de groupe. Je pense que c'est une essence qui minimise le nombre d'étapes de développement personnel.

Recommended Posts

[Python] Comment forcer une méthode d'une sous-classe à effectuer un processus spécifique
[Python] Comment lire le fichier csv (méthode read_csv du module pandas)
Comment écrire un type liste / dictionnaire de Python3
[Python] Comment créer une liste de chaînes de caractères caractère par caractère
Comment mélanger une partie de la liste Python (au hasard.shuffle)
Comment utiliser la méthode __call__ dans la classe Python
J'ai essayé "Comment obtenir une méthode décorée en Python"
Comment développer dans un environnement virtuel Python [Memo]
Comment obtenir une liste d'exceptions intégrées pour python
Comment remplacer une méthode de type défini par l'utilisateur générée par python swig
[Python] Comment faire PCA avec Python
[Python] Comment supprimer des lignes et des colonnes dans une table (liste des options de méthode de dépôt)
Développez un dictionnaire imbriqué Python pour faire quelque chose comme MultiIndex de Pandas
Comment déterminer l'existence d'un élément sélénium en Python
Comment vérifier la taille de la mémoire d'une variable en Python
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
[Python] Comment créer une matrice de motifs répétitifs (repmat / tile)
[Python] Résumé de l'utilisation des pandas
[Python] Comment rendre une classe itérable
Comment faire R chartr () en Python
[Python] Comment convertir une liste bidimensionnelle en liste unidimensionnelle
[Python] Comment inverser une chaîne de caractères
Comment obtenir stacktrace en python
Comment faire un test de sac avec python
[Python2.7] Résumé de l'utilisation d'unittest
Résumé de l'utilisation de la liste Python
[Python2.7] Résumé de l'utilisation du sous-processus
[Python] Comment utiliser l'instruction for. Une méthode d'extraction en spécifiant une plage ou des conditions.
Comment exécuter des scripts Maya Python
[Question] Comment utiliser plot_surface de python
Comment envoyer une image visualisée des données créées en Python à Typetalk
[Python] Comment mettre n'importe quel nombre d'entrées standard dans la liste
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
Comment bien formater une liste de dictionnaires (ou d'instances) en Python
Comment arrêter le programme jusqu'à une date et une heure spécifiques en python
Comment calculer la volatilité d'une marque
Comment lire un fichier CSV avec Python 2/3
[Python] Comment utiliser deux types de type ()
Comment ouvrir un navigateur Web à partir de python
Comment effacer un taple dans une liste (Python)
Comment faire un traitement parallèle multicœur avec python
Comment incorporer des variables dans des chaînes python
Résumé de la façon d'importer des fichiers dans Python 3
Comment créer un fichier JSON en Python
Comment générer un objet Python à partir de JSON
Résumé de l'utilisation de MNIST avec Python
Comment ajouter un chemin de recherche de module Python
Comment spécifier des attributs avec Mock of Python
Comment notifier les canaux Discord en Python
Comment obtenir des éléments de type dictionnaire de Python 2.7
[Python] Comment dessiner un histogramme avec Matplotlib
Comment compter les nombres dans une plage spécifique
Comment réaliser quelque chose comme une liste de void * (ou de type de variante) dans Go?
[Circuit x Python] Comment trouver la fonction de transfert d'un circuit en utilisant Lcapy
[python] Comment trier par le Nth Mth élément d'un tableau multidimensionnel
Comment obtenir une liste de fichiers dans le même répertoire avec python
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
Mémo connecté à HiveServer2 d'EMR avec python