在python中的类实例之间共享选项

时间:2012-01-07 13:00:25

标签: python

为什么字典内容在类实例之间共享,但字符串不共享?

测试代码:

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()

输出:

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

在字典属性中实例之间共享选项是否正确?

2 个答案:

答案 0 :(得分:3)

files_names是类Config的类属性,因此它由此类的所有实例共享。 file_name_1file_name_2最初也是类属性(设置为None),但您在set_file_names方法中的实例中重新绑定它们,因此它们成为实例属性,对每个实例都是私有的,那个时候。

您的想法是使用一个类属性,它是一个可变容器(dict),包含所有实例共有的配置,并且可以动态更新。

如果您仍想使用单个字符串属性file_name_1file_name_2,但希望在所有实例之间共享它们,则可以执行以下操作之一:

  • 重新绑定属性,而不是使用set_file_names代替Config.file_name_1 = whatever
  • self.file_name_1 = whatever中创建实例属性
  • 使set_file_names方法成为类方法(使用@classmethod装饰器),以便它可以在类上运行,而不是在实例上运行。
  • 根本不要实例化Config类,单个它无论如何都是单例。使用Config代替Config()

答案 1 :(得分:2)

虽然我不确定在你的情况下Config是否需要单例,但是将dict配置为一个Config实例的方法可能是:

class Config(object):
    file_names  = None
    file_name_1 = None
    file_name_2 = None

    def __init__(self):
        if self.file_names is None:
            self.file_names = dict()
            ...

但是,我坚信它是一个更好的设计,只在您的应用程序中实例化一次Config并传递实例:

class CommandLineParser(object):
    def __init__(self, config):
        self.cfg = config
        self.start()

从更一般的角度来说,最好明确地传递上下文信息。