Detailed explanation of python function parameter transmission dict and list and set and other types of problems
- 2021-10-16 02:23:23
- OfStack
When passing a parameter, you pass a variable object, which is actually a pointer/reference to a memory address
This title is my conclusion, which I found in the process of doing the project. Anyone who has studied C knows that function parameters can be passed by values or pointers. The benefits of pointers are not repeated here.
First, go to the code to see the effect:
def trans(var):
return var
source = {1: 1}
dist = trans(source)
source[2] = 2
print(source)
print(dist)
Run results:
{1: 1, 2:2}
{1: 1, 2:2}
It can be seen that when source is changed, dist is also changed. The reason is that source is a mutable object, and when you pass a parameter, you pass its reference (pointer to C). dist and source both point to the same memory space. When running source [2] = 2, it is a change to the data in the memory space, so dist changes accordingly.
What's the effect? There should be many scenes, but my qualifications are still young, so I can't think of typical scenes, so take my own project as an example.
I defined a class in the project, which is used to read and write configurations, pre-store some json configurations, and the client can read the configurations. When the pre-stored configurations do not include the configurations read by the client, they are read from the device.
I need this class to instantiate multiple objects corresponding to multiple clients. But I want the pre-stored configuration to be public, so that for unfamiliar configurations, all client requests are not required to be read from the device.
1 This is what I wrote at first:
global dataset
dataset = {}
class Config(object):
def __init__(self, device_url):
self.device_url = device_url
def get_config(self, key):
global dataset
if key in dataset:
return dataset.get(key)
else:
# Pass device_url Gets the configuration from the device, if the value is assigned to the value
dataset[key] = value
return value
def other_func(self):
# Other functions, following device_url Pertaining to
pass
Later, I needed multiple public configurations, even reaching more than 1,000 copies. Obviously, global variables can't be well satisfied. Because I want to share memory, I pass the mutable object and change the code to this:
class Config(object):
def __init__(self, dataset, device_url): # Passing mutable objects dataset
self.dataset = dataset
self.device_url = device_url
def get_config(self, key) :
if key in self.dataset:
return self.dataset.get(key)
else:
# Pass device_url Gets the configuration from the device, if the value is assigned to the value
self.dataset[key] = value # Variable object dataset Assignment, other instantiated dataset Property values also change
return value
def other_func(self):
# Other functions, following device_url Pertaining to
pass
Lists, dictionaries and collections are not necessarily mutable objects
There is a pile of information on the Internet saying that lists, dictionaries and collections are mutable objects, which is not completely correct. {} [] set ((,)) constants are not mutable objects.
The above Config class cannot share configuration if it passes {} when instantiated.
config1 = Config({})
config2 = Config({})
config1.dataset[1] = 1
print(repr(config1.dataset))
print(repr(config2,dataset))
The above operation result is
'{1: 1}'
'None'
But if so
share_var = {}
config1 = Config(share_var)
config2 = Config(share_var)
config1.dataset[1] = 1
print(repr(config1.dataset))
print(repr(config2,dataset))
The result of the run will become:
'{1: 1}'
'{1: 1}'
share_var is a mutable object, whereas {} is an immutable object, although the values of share_var and {} are identical.
To get a deeper understanding, you need to understand the namespace of python.
Things to pay attention to when passing parameters and variable object parameters
If you don't want to pass references/pointers to operate the corresponding memory space, be careful not to pass dictionaries, lists, collections, classes or instantiated objects of classes when passing parameters
When passing variable object parameters, be careful not to pass the constant {} [] set ((,)). It is best to give a variable before passing the parameter, and pass this variable when passing the parameter.
Knowing the principle may not directly pass constants, but the following situations may occur:
def func1(mutable_object, flag):
if flag:
return mutable_object
else:
return {}
def func2(mutable_object):
# something to do with mutable_object
pass
func2(func1(mutable_object, False)) # Here func1(mutable_object, False) Returns the {} Yes 1 Immutable objects