繁体   English   中英

委托Python中的dict类

[英]Delegate to a dict class in Python

在Python 3中,我有一个列表和dicts树,我从另一个库中获取。 我想用包含更多行为的对象来检测该树中的dicts(为简单的dict类提供更丰富的模型)。 我试过用dict的子类替换这些对象的类,但是不允许这样做:

class MyClass(dict): pass
{}.__class__ = MyClass

TypeError: __class__ assignment: only for heap types失败TypeError: __class__ assignment: only for heap types

所以我试图编写一个包装器或适配器或委托类:

class InstrumentedDict(object):
    """
    Instrument an existing dictionary with additional
    functionality, but always reference and mutate
    the original dictionary.

    >>> orig = {'a': 1, 'b': 2}
    >>> inst = InstrumentedDict(orig)
    >>> hasattr(inst, '__getitem__')
    True
    >>> inst.__getitem__('a')
    1
    >>> inst['a']
    1
    >>> inst['c'] = 3
    >>> orig['c']
    3
    >>> inst.keys() == orig.keys()
    True
    """
    def __init__(self, orig):
        self._orig = orig

    def __getattribute__(self, name):
        orig = super(InstrumentedDict, self).__getattribute__('_orig')
        return orig.__getattribute__(name)

但是,docte在inst['a']TypeError: 'InstrumentedDict' object is not subscriptable而失败TypeError: 'InstrumentedDict' object is not subscriptable 但请注意,它无法调用__hasattr____getitem__

我希望将所有行为委托给基础字典,并且我不想考虑或明确地委托字典的整个签名。

重要的是,无论这个类做什么都应该影响底层的dict(而不是创建对值的单独引用)。 理想情况下,它不应强加或否定底层映射的可变性,但应反映其行为。

是否有一个简单而优雅的解决方案满足指定的接口,但不需要显式镜像签名(例如在此实现中 )?

编辑:为了澄清,我想在不创建新副本的情况下覆盖现有字典上的行为,这样如果修改了经过检测的副本,原始副本也是如此。

冒着完全忽略问题的风险......

是否有任何理由建立代理而不是仅仅是继承dict 就像是:

class InstrumentedDict(dict):
    """ Walks like a dict, talks like a dict... """

评论后编辑:

啊,我明白了:)有道理......

似乎UserDict就是答案,请查看:

from collections import UserDict

class InstrumentedDict(UserDict):

    def __init__(self, data):
        super(InstrumentedDict, self).__init__()
        self.data = data

remote_dict = {"a": 1}
instr_dict = InstrumentedDict(remote_dict)

print(instr_dict)  # {'a': 1}

instr_dict["b"] = 2

print(instr_dict)  # {'a': 1, 'b': 2}
print(remote_dict)  # {'a': 1, 'b': 2}

UserDict似乎是我们无法直接将dict子类化的古代遗物。 但它很有用,因为它暴露了data属性。 这就是文档所说的全部内容: UserDict

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM