Why dictionary content shared between class instances, but strings not shared?
Test code:
class Config(object):
file_names = dict()
file_name_1 = None
file_name_2 = None
def __init__(self):
if not self.file_names:
print "DEBUG: Config(): set initial values"
self.file_names["0"] = None
self.file_names["1"] = None
def set_file_names(self, file_names):
self.file_name_1 = file_names[0]
self.file_names["0"] = file_names[0]
self.file_name_2 = file_names[1]
self.file_names["1"] = file_names[1]
class CommandLineParser(object):
def __init__(self):
self.cfg = Config()
self.start()
def start(self):
self.cfg.set_file_names(("file_1.log", "file_2.log"))
print self.__class__.__name__, "FileName1 (str) :", self.cfg.file_name_1
print self.__class__.__name__, "FileName1 (dict):", self.cfg.file_names["0"]
class LogProcessor(object):
def __init__(self):
self.cfg = Config()
self.cmdln = CommandLineParser()
print self.__class__.__name__, "FileName1 (str) :", self.cfg.file_name_1
print self.__class__.__name__, "FileName1 (dict):", self.cfg.file_names["0"]
if __name__ == '__main__':
processor = LogProcessor()
Output:
DEBUG: Config(): set initial values
CommandLineParser FileName1 (str) : file_1.log
CommandLineParser FileName1 (dict): file_1.log
LogProcessor FileName1 (str) : None
LogProcessor FileName1 (dict): file_1.log
Is it a right way to share options between instances in dictionary attribute?
files_namesis a class attribute of your classConfigso it is shared by all instances of this class.file_name_1andfile_name_2are also initially class attributes (set toNone) but you rebind them in instances inside theset_file_namesmethod so they become instance attributes, private to each instance, at that time.Your idea to use a class attribute which is a mutable container (
dict) to contain configuration common to all instances and which can be updated dynamically is good.If you still want to use the individual string attributes
file_name_1andfile_name_2but you want them to be shared between all instances, then you can do one of the following things:set_file_namesby usingConfig.file_name_1 = whateverinstead ofself.file_name_1 = whateverset_file_namesmethod a class method (use the@classmethoddecorator) so that it will operate on the class, not on the instance.Configinstead ofConfig().