在Bunch类型对象中设置和获取属性
为了简单解析/创建 JSON,机器学习应用程序通常使用Bunch对象,例如https://github.com/dsc/bunch/blob/master/bunch/__init__.py
获取时,有一个嵌套的 EAFP 习语,它检查dict.get()函数,然后尝试使用字典方括号语法访问它,即
class Bunch(dict):
def __getattr___(self, k):
try:
return object.__getattribute__(self, k)
except AttributeError:
try:
return self[k]
except KeyError:
raise AttributeError
当试图设置一个属性时,
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)
似乎sklearn实现遵循相同的思路,但检查较少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
嵌套的 EAFP 似乎有点难以维护,我的问题是:
- 有没有更简单的方法来处理 Bunch 数据对象的 get 和 set 函数?
- 是否有其他类似 Dict 的对象允许属性和键之间的可变性?
- Bunch 对象的
.update()函数应该如何工作,浅拷贝还是深拷贝?或者只是让默认dict.update()做它所做的? 理解 dict.copy() - 浅还是深?