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

时间:2019-03-26 21:19:02

标签: python oop

我正在写另一个“自行车”来读取.ini文件,以获得一些高级Python和OOP的经验。另外,我发现默认的Python的configparser访问样式对于眼睛来说有点不愉快,即:something = config['section']['parameter']而不是更让人眼花{乱的something = config.section.parameter

我最终完成了这种设计:

  • ConfigStorage对象可将参数/值对保留为字典;
  • Config对象来管理存储对象中的数据。
__getattribute__对象中的

Config被覆盖,因此我可以通过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

    def __del__(self):
        instance_id = str(id(self))
        keys_to_delete = []
        for key in _ConfigStorage.config:
            if instance_id in key:
                keys_to_delete.append(key)
        for key_to_delete in keys_to_delete:
            del _ConfigStorage.config[key_to_delete]

如何通过对象属性访问词典数据来改进设计?

2 个答案:

答案 0 :(得分:1)

我认为此实现适合您的需求:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link
      rel="stylesheet"
      href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
/>
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
<div id="map"></div>

无需编写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) # value print(config.not_a_key) # AttributeError: ... _ConfigStorage,无需无限递归,可以通过点表示法进行访问。

答案 1 :(得分:0)

傻,但是我找到了解决问题的更优雅的方法。

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