如何将对象 A 的实例的数据绑定到对象 B 的对应实例?

我正在编写另一个“自行车”来读取 .ini 文件,以获得一些高级 Python 和 OOP 的经验。此外,我发现默认的 Python 的 configparser 访问风格对眼睛来说有点不舒服,即:something = config['section']['parameter']而不是更多的 eye-candish something = config.section.parameter

我已经结束了这个设计:

  • ConfigStorage 对象将参数/值对保留为字典;

  • Config 对象来管理存储对象中的数据。

__getattribute__in Configobject 被覆盖,因此我可以ConfigStorage通过Config对象的属性名称访问字典中的值(目标!)。

Config对象只有一个实例时,系统工作正常。当我尝试使用多个配置(并因此实例化新Config对象来管理它们)时,我意识到这ConfigStorage一个通用的.

我试图ConfigStorage为每个Config对象创建新实例,但 Python 在这段代码中达到了最大递归深度(为什么?):

class _ConfigStorage(object):

    def __init__(self):

        self.config = dict()



class Config(object):

    def __getattribute__(self, name):

        if name in self.c.config:

            return self.c.config[name]

        else:

            raise AttributeError("No parameter named [%s]" % name)


    def __init__(self, file):

        self.c = _ConfigStorage()

        with open(file, 'r') as f:

            for config_line in f:

                key = # getting key from line

                value = # getting value

                self.c.config[key] = value

最后,我让我的代码工作了,但我发现这个解决方案非常粗糙并且被黑魔法污染了。我通过向字典键添加Config对象 ID的字符串表示来分离存储对象中的数据。该ConfigStorage对象仍是单身。

还__del__需要方法,因为 GC 不知道存储中的不必要数据,我必须手动删除它们。糟透了。


class _ConfigStorage(object):

    config = dict()



class Config(object):

    def __getattribute__(self, name):

        key = str(id(self)) + name

        if key in _ConfigStorage.config:

            return _ConfigStorage.config[key]

        else:

            raise AttributeError("No parameter named [%s]" % name)


    def __init__(self, file):

        with open(file, 'r') as f:

            for config_line in f:

                key = str(id(self) + # getting key from line

                value = # getting value

                _ConfigStorage.config[key] = value


如何改进设计,能够通过对象属性访问字典数据?


浮云间
浏览 153回答 2
2回答

缥缈止盈

我认为此实现适合您的需求:class Config(object):    def __getattr__(self, name):        if name in self.config:            return self.config[name]        else:            raise AttributeError("No parameter named [%s]" % name)    def __init__(self, file=None):        # changed to make it work without real file        self.config = {'key': 'value'}config = Config()print(config.key)  # valueprint(config.not_a_key)  # AttributeError: ...不需要写_ConfigStorage和__del__,没有无限递归,通过点表示法访问。

素胚勾勒不出你

愚蠢,但我找到了更优雅的方法来解决我的问题。class Config(object):    config = dict()    def __getattribute__(self, name):        if name in Config.config:            return Config.config[name]        else:            raise AttributeError("No parameter named [%s]" % name)    def __init__(self, file):        try:            with open(file, 'r') as f:                for config_line in f:                    config_line = config_line.strip()                    eq_position = config_line.find('=')                    key = config_line[:eq_position].strip()                    value = config_line[eq_position + 1:].strip()                    Config.config[key] = value        except FileNotFoundError:            print('File not found')
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python