For simplicity to parse/create JSON, machine learning applications usually uses the Bunch
object, e.g. https://github.com/dsc/bunch/blob/master/bunch/__init__.py
When getting, there's a nested EAFP idiom that checks through the dict.get()
function and then trying to access it with dictionary square bracket syntax, i.e.
class Bunch(dict):
def __getattr___(self, k):
try:
return object.__getattribute__(self, k)
except AttributeError:
try:
return self[k]
except KeyError:
raise AttributeError
And when trying to set an attribute,
def __setattr__(self, k, v):
try:
# Throws exception if not in prototype chain
object.__getattribute__(self, k)
except AttributeError:
try:
self[k] = v
except:
raise AttributeError(k)
else:
object.__setattr__(self, k, v)
Seems like the sklearn
implementation follows the same train of thought but has lesser checks https://github.com/scikit-learn/scikit-learn/blob/2beed5584/sklearn/utils/__init__.py#L61
class Bunch(dict):
def __init__(self, **kwargs):
super().__init__(kwargs)
def __setattr__(self, key, value):
self[key] = value
def __dir__(self):
return self.keys()
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(key)
def __setstate__(self, state):
# Bunch pickles generated with scikit-learn 0.16.* have an non
# empty __dict__. This causes a surprising behaviour when
# loading these pickles scikit-learn 0.17: reading bunch.key
# uses __dict__ but assigning to bunch.key use __setattr__ and
# only changes bunch['key']. More details can be found at:
# https://github.com/scikit-learn/scikit-learn/issues/6196.
# Overriding __setstate__ to be a noop has the effect of
# ignoring the pickled __dict__
pass
The nested EAFP seems a little hard to maintain, my questions here are:
- Is there a simpler way to handle get and set functions for Bunch data objects?
- Are there any other Dict like object that allows mutability between attributes and keys?
- How should Bunch object's
.update()
function work, shallow or deep copying? Or just let the defaultdict.update()
do what it does? Understanding dict.copy() - shallow or deep?
from Set and Get attributes in Bunch type object
No comments:
Post a Comment