首页 > 解决方案 > 带有内部类属性的 Python 自定义字典

问题描述

class DownloadDict(dict):
    """dictionary that will fetch if missing data"""
    def __init__(self, name, *args, **kwargs):
        super(dict, self).__init__(*args, **kwargs)
        self.name = name

    def download(self):
        print(f"Fetching New Data: {self.name}")
        [self.__setitem__(key,value) for (key, value) in makeReferenceJson()[self.name].items()]


    def __getitem__(self, key):
        try:
            return getattr(self, key)
        except AttributeError:
            self.download()
            return getattr(self, key)

makeReferenceJson执行提取。

我的目标是让这个字典类像普通字典一样运行,除非有键未命中;我希望它执行一次获取并重试(我有一个几乎不会更新的 json 字典,但是当它更新时,我想在不轮询 API 的情况下本地处理它)。

问题是self.name = namename值分配给一个"name"键并显示在我所有正常的字典操作中(例如.keys()

有没有办法轻松(无需自定义编写所有方法)创建私有类属性?

旁白:我之所以采用这种方法,是因为我的代码中到处都有字典,我以不同的方式调用它们,我想在一个地方更新它们的构造,而不是搜索所有实例——所以 API 需要保持不变。(类似myDict.get(key)myClass.dict[key]不会在这里工作的东西

马上:

d = DownloadDict("Dataset1")
d
# {"name":"Dataset1"}
d.name
# "Dataset1"

期望的行为:

d = DownloadDict("Dataset1")
d
# {}
d.name
# "Dataset1"

在修补和阅读评论之后,我做了一些小的调整,并认为我已经将这个问题缩小到了__getitem__覆盖范围。

我不确定在该函数中调用什么/如何调用getitem(我不想要self.getitem;可能有一些涉及 super 的语法?)但我的问题是使用getattr其他人指出的 - 因为我有目的地避免写入类属性

标签: pythonclassdictionary

解决方案


这个:

在 python 中为现有的内置类方法添加装饰器

让我想起了调用子类方法的语法——解决了我的问题

class DownloadDict(dict):
    """dictionary that will fetch if missing data"""
    def __init__(self, name, *args, **kwargs):
        super(DownloadDict, self).__init__(*args, **kwargs)
        self.name = name

    def download(self):
        [self.__setitem__(key,value) for (key, value) in makeReferenceJson()[self.name].items()]

    def __getitem__(self, key):
        try:
            return super(DownloadDict, self).__getitem__(key)
        except AttributeError:
            self.download()
            return super(DownloadDict, self).__getitem__(key)

推荐阅读