Suppose one wishes to instantiate a class:
Summary
def __init__(self,
num: int = 5,
text: str = 'txt',
listed: list = [],
dicted: dict = {}
):
self.num = num
self.text = text
self.listed = listed
self.dicted = dicted
# for debugging purposes
def print(self, last=None):
print(self.num, self.text,
self.listed, self.dicted,
f'# {last}' if last else '')
It may be important to have an option to provide both the list and the dict arguments manually - e.g. in the case one needs to create an instance dynamically. Such as:
Summary
cls = Test
args = {
'num': 5,
'text': 'txt',
'list': [],
'dict': {}
}
instance = cls(**args)
Creating new instances of the class manually, however, introduces a rather interesting surprise to the behaviour of all those instances, at once. Specifically, the following code:
Summary
t1 = Test()
t2 = Test()
t1.print('t1: start')
t2.print('t2: start\n')
t1.num = 3
t2.text = 'next'
t1.print('t1: num_text')
t2.print('t2: num_text\n')
t1.list.append('app')
t2.dict['key'] = 'val'
t1.print('t1: list_dict')
t2.print('t2: list_dict')
Will print the following:
Summary
5 txt [] {} # t1: start
5 txt [] {} # t2: start
3 txt [] {} # t1: num_text
5 next [] {} # t2: num_text
3 txt ['app'] {'key': 'val'} # t1: list_dict
5 next ['app'] {'key': 'val'} # t2: list_dict
If this is not the prime example of the most unintuitive feature a class / function declaration may have, I do not dare to imagine what that may even be. Certainly, it is possible to avoid such a problem via:
Summary
def __init__(self,
num: int = 5,
text: str = 'txt',
listed = None,
dicted = None
):
self.num = num
self.text = text
self.list = listed or []
self.dict = dicted or []
Yet is that not precisely what the author of the class would expect to happen in the first declaration, as well? Under which circumstances could one intend to link all the instances of a particular class to one single list / dict reference, declared in the instantiating __init__ in a manner identical to the passed/copied by value, not by reference, int / str? Was there any discussion about it? Is this simply “the way it’s come to be”?