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
performs a fetch.
My goal is for this dictionary class to operate as a normal dict, except when there is a key-miss; I want it to perform a fetch and try again (I have a json dict that hardly ever gets updated, but when it does I want to handle it natively w/out polling an API).
The problem is self.name = name
assigns the name
value to a "name"
key and shows up in all of my normal dictionary actions (like .keys()
)
Is there a way to easily (without custom writing ALL of the methods) create a private class attribute?
Aside: I'm taking this approach because I have dictionaries all over my code that I invoke in different ways and I want to update their construction in one place instead of hunting down all of the instance -- so the API needs to remain unchanged. (Something like myDict.get(key)
or myClass.dict[key]
wont work here
Right now:
d = DownloadDict("Dataset1")
d
# {"name":"Dataset1"}
d.name
# "Dataset1"
Desired Behavior:
d = DownloadDict("Dataset1")
d
# {}
d.name
# "Dataset1"
After tinkering & reading through the comments I've made some minor adjustments, and think I've narrowed down this issue to the __getitem__
override.
I'm not sure what/how to call the getitem within that function (I don't want self.getitem; there's probably some syntax involving super?) but my issue is using the getattr
as others have pointed out -- since I'm purposefully trying to avoid writing to the class attributes