[Python] How to force a method of a subclass to do something specific

I want to force a specific process on a subclass

When designing a subclass that inherits a certain class in Python, there are times when you want the inherited destination to do this kind of processing.

For example, you want to always call super () .__ init __ () when __init __ is called ...

Not limited to __init__, the process of" I want to override the method of the parent class, but I want to call the method of the parent class as it is! "Often appears, but I forgot to write the process to call the method of the parent class. I don't want to throw an error, and the specification itself that calls the method of the parent class is troublesome in the first place.

This time, when the method f of the child class is called, we will implement an implementation in which the method f of the parent class is always called after the processing.

manner

** Rewrite "child class function f" to "function new_f that executes child class function f and parent class function f" ** Write a metaclass that will do that

What is a metaclass? The story will be different this time. For the time being, think of it as a class that modifies the way classes are defined.

I believe that even people who are not familiar with it can do anything by copying and pasting the code below and rewriting the decorate method.

Premise

Python: 3.7.2 (Maybe OK for Python3, only the metaclass specification method is different for Python2)

code

class ParentCaller(type):
    def __new__(cls, name, base, attr):
        #Prevent f in Parent class from calling f in Parent class
        if name != "Parent":
            #Make the function f automatically decorated when the class is created
            attr["f"] = cls.decorate(attr["f"])
        return super().__new__(cls, name, base, attr)

    @classmethod
    def decorate(cls, f):
        #When the function f is received, f and Parent.Run f as a set new_Returns 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!

Summary

When writing a library like Tensorflow that people inherit and use, I want to avoid the promise of "Run hogehoge here!" As much as possible. In such a case, write a metaclass and call hogehoge without your knowledge.

It seems that metaprogramming is difficult to read and hated in group development. I think that it is an essence that minimizes man-hours for personal development.

Recommended Posts

[Python] How to force a method of a subclass to do something specific
[Python] How to read a csv file (read_csv method of pandas module)
How to write a list / dictionary type of Python3
[Python] How to make a list of character strings character by character
How to shuffle a part of a Python list (at random.shuffle)
How to use the __call__ method in a Python class
I tried "How to get a method decorated in Python"
How to develop in a virtual environment of Python [Memo]
How to get a list of built-in exceptions in python
How to override a user-defined method generated by python swig
How to write a Python class
[Python] How to do PCA in Python
[Python] How to delete rows and columns in a table (list of drop method options)
Expand a Python nested dictionary to do something like Pandas' MultiIndex
How to determine the existence of a selenium element in Python
How to check the memory size of a variable in Python
How to check the memory size of a dictionary in Python
[Python] How to make a matrix of repeating patterns (repmat / tile)
[Python] Summary of how to use pandas
[Python] How to make a class iterable
How to do R chartr () in Python
[Python] How to convert a 2D list to a 1D list
[Python] How to invert a character string
How to get a stacktrace in python
How to do portmanteau test with python
[Python2.7] Summary of how to use unittest
Summary of how to use Python list
[Python2.7] Summary of how to use subprocess
[Python] How to use the for statement. A method of extracting by specifying a range or conditions.
How to run a Maya Python script
[Question] How to use plot_surface of python
How to send a visualization image of data created in Python to Typetalk
[Python] How to put any number of standard inputs in a list
[Introduction to Python] How to sort the contents of a list efficiently with list sort
How to format a list of dictionaries (or instances) well in Python
How to stop a program in python until a specific date and time
How to calculate the volatility of a brand
How to read a CSV file with Python 2/3
A simple example of how to use ArgumentParser
[Python] How to use two types of type ()
How to create a Python virtual environment (venv)
How to open a web browser from python
How to clear tuples in a list (Python)
How to do multi-core parallel processing with python
How to embed a variable in a python string
Summary of how to import files in Python 3
How to create a JSON file in Python
How to generate a Python object from JSON
Summary of how to use MNIST in Python
How to add a Python module search path
How to specify attributes with Mock of python
How to notify a Discord channel in Python
How to get dictionary type elements of Python 2.7
[Python] How to draw a histogram in Matplotlib
How to count numbers in a specific range
How to achieve something like a list of void * (or variant) in Go?
[Circuit x Python] How to find the transfer function of a circuit using Lcapy
[python] How to sort by the Nth Mth element of a multidimensional array
How to get a list of files in the same directory with python
[Introduction to Python] How to get the index of data with a for statement
A memo connected to HiveServer2 of EMR with python