[Python] Inherit a class with class variables

If there are multiple classes that inherit from the parent class that has class variables Note that the behavior when the child class accesses the class variable was suspicious.

Conclusion (?):

--Mutable class variables are likely to be shared even in the inherited child class. --Overwrite the same variable in the child class if you want to manage them separately

Symptoms

#Parent class
class AbstClass:
    class_number = 0
    dict_number = {'class': 0}

#Child class 1
class Class1(AbstClass):
    def __init__(self):
        self.class_number = 1
        self.dict_number['class'] = 1

#Child class 2
class Class2(AbstClass):
    def __init__(self):
        self.class_number = 2
        self.dict_number['class'] = 2

obj1 = Class1()
print(obj1.class_number, obj1.dict_number['class']) # 1,1 ← Understand
obj2 = Class2()
print(obj2.class_number, obj2.dict_number['class']) # 2,2 ← Understand
print(obj1.class_number, obj1.dict_number['class']) # 1, 2 ←!?

It is easy to understand if "two child classes are accessing the class variables of the same parent class", In the above example

--class_number is managed separately by two classes --dict_number is shared by two classes → Overwrites dict_numer rewritten in Class1 when Class2 () is done

It has become.

Cause hypothesis

Is mutable / immutable involved? I guess. In other words

--mutable class variables (dict_number above): shared by child classes --immutable class variables (class_number above): managed separately in child classes

In fact, if you define a tuple of class_number_tuple = (0,) in AbstClass, The same behavior as class_number was confirmed. (* Int is immutable. Reference: [GAMMASOFT: Python built-in data type classification table (mutable, etc.)] (https://gammasoft.jp/blog/python-built-in-types/))

Countermeasures

Redefine class variables in child classes:

class Class1(AbstClass):
    class_number = 0
    dict_kv = {'class': 0}

class Class2(AbstClass):
    class_number = 0
    dict_kv = {'class': 0}

And, in each instance, the class variable of each class is prioritized = it will be managed separately.

However, if you want, I want you to automatically raise an exception as a language.

――In fact, when I put a list in the key of the dictionary, I get angry with unhashable --If it is possible to specify "class variables to be shared" and "class variables to be overwritten by child classes" like @abstractmethod of ABC ...

As a current measure,

--Do not define class variables in abstract classes that are supposed to be inherited (as mentioned above, it is safer to redefine in child classes, so it is simply a waste of lines) --Use delegation instead of inheritance when you need to access class variables of other classes (ideal) --Read the source code of the inherited class even at the beginning (reality)

Is it about ... I would appreciate it if you could tell me any good measures.

Recommended Posts

[Python] Inherit a class with class variables
Create a Python function decorator with Class
Build a blockchain with Python ① Create a class
[Note] Create a one-line timezone class with python
Trouble with Python pseudo-private variables and class inheritance
Python: Class and instance variables
Python class variables and instance variables
Make a fortune with Python
Create a directory with python
How to write a Python class
Solve ABC163 A ~ C with Python
Operate a receipt printer with python
A python graphing manual with Matplotlib.
Landmines hidden in Python class variables
Let's make a GUI with python.
Solve ABC166 A ~ D with Python
Class variables
Create a virtual environment with Python!
I made a fortune with Python.
[Python] Variables
Building a virtual environment with Python 3
Solve ABC168 A ~ C with Python
Class variables
[Python] Generate a password with Slackbot
Solve ABC162 A ~ C with Python
Solve ABC167 A ~ C with Python
Solve ABC158 A ~ C with Python
Let's make a graph with python! !!
I made a daemon with Python
Write a batch script with Python3.5 ~
[Road to Python Intermediate] Call a class instance like a function with __call__
[Pyenv] Building a python environment with ubuntu 16.04
Generate a first class collection in Python
Spiral book in Python! Python with a spiral book! (Chapter 14 ~)
Creating a simple PowerPoint file with Python
[Python] A program that creates stairs with #
Building a Python3 environment with Amazon Linux2
Let's make a shiritori game with Python
Install Python as a Framework with pyenv
[Python] How to make a class iterable
Add a Python data source with Redash
I made a character counter with Python
[Python] Drawing a swirl pattern with turtle
I drew a heatmap with seaborn [Python]
[Python] Create a virtual environment with Anaconda
Let's create a free group with Python
A memo with Python2.7 and Python3 on CentOS
Building a Python 3.6 environment with Windows + PowerShell
Map rent information on a map with python
Search the maze with the python A * algorithm
Playing card class in Python (with comparison)
Let's make a voice slowly with Python
Created a darts trip with python (news)
[Python] A quick web application with Bottle!
[AtCoder] Solve ABC1 ~ 100 A problem with Python
Write a TCP client with Python Twisted
What I did with a Python array
Solve AtCoder ABC168 with python (A ~ D)
Create a word frequency counter with Python 3.4
Try HTML scraping with a Python library
I made a Hex map with Python