如何在Python中使用抽象基类实现字典?

如何在Python中使用抽象基类实现字典?,第1张

如何在Python中使用抽象基类实现字典

如何使用抽象基类实现字典?

一个很好的答案将演示如何进行这项工作,尤其是在不继承dict的情况下。

这是错误消息:

TypeError: Can't instantiate abstract class D with abstract methods__delitem__, __getitem__, __iter__, __len__, __setitem__

事实证明,必须实现它们才能使用抽象基类(ABC)

MutableMapping

实作

因此,我实现了一个映射,该映射在大多数方面像dict一样工作,该映射使用对象的属性引用dict进行映射。(委托与继承不同,因此我们只委托给实例

__dict__
,我们可以使用任何其他临时映射,但是您似乎并不关心实现的那部分。这样做很有意义。在Python
2中采用这种方式,因为MutableMapping在Python 2中没有
__slots__
,所以您要创建一种
__dict__
方式。在Python
3中,可以通过设置完全避免字典
__slots__


from collections.abc import MutableMappingclass D(MutableMapping):    '''    Mapping that works like both a dict and a mutable object, i.e.    d = D(foo='bar')    and     d.foo returns 'bar'    '''    # ``__init__`` method required to create instance from class.    def __init__(self, *args, **kwargs):        '''Use the object dict'''        self.__dict__.update(*args, **kwargs)    # The next five methods are requirements of the ABC.    def __setitem__(self, key, value):        self.__dict__[key] = value    def __getitem__(self, key):        return self.__dict__[key]    def __delitem__(self, key):        del self.__dict__[key]    def __iter__(self):        return iter(self.__dict__)    def __len__(self):        return len(self.__dict__)    # The final two methods aren't required, but nice for demo purposes:    def __str__(self):        '''returns simple dict representation of the mapping'''        return str(self.__dict__)    def __repr__(self):        '''echoes class, id, & reproducible representation in the REPL'''        return '{}, D({})'.format(super(D, self).__repr__(),  self.__dict__)
示范

并演示用法:

>>> d = D((e, i) for i, e in enumerate('abc'))>>> d<__main__.D object at 0x7f75eb242e50>, D({'b': 1, 'c': 2, 'a': 0})>>> d.a0>>> d.get('b')1>>> d.setdefault('d', []).append(3)>>> d.foo = 'bar'>>> print(d){'b': 1, 'c': 2, 'a': 0, 'foo': 'bar', 'd': [3]}

为了确保dict API,吸取的教训是您可以随时检查

collections.abc.MutableMapping

>>> isinstance(d, MutableMapping)True>>> isinstance(dict(), MutableMapping)True

尽管由于集合导入上的注册,字典通常将成为MutableMapping的一个实例,但并非总是如此:

>>> isinstance(d, dict)False>>> isinstance(d, (dict, MutableMapping))True

完成本练习后,对我来说很明显,使用抽象基类只能为该类用户提供标准API的保证。在这种情况下,将向假定MutableMapping对象的用户保证Python的标准API。

注意事项:

fromkeys
类的构造方法未实现。

>>> dict.fromkeys('abc'){'b': None, 'c': None, 'a': None}>>> D.fromkeys('abc')Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: type object 'D' has no attribute 'fromkeys'

可以掩盖内置的dict方法,例如

get
setdefault

>>> d['get'] = 'baz'>>> d.get('get')Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: 'str' object is not callable

再次取消屏蔽非常简单:

>>> del d['get']>>> d.get('get', 'Not there, but working')'Not there, but working'

但是我不会在生产中使用此代码。


没有字典的演示,Python 3:

>>> class MM(MutableMapping):...   __delitem__, __getitem__, __iter__, __len__, __setitem__ = (None,) *5...   __slots__ = ()...>>> MM().__dict__Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: 'MM' object has no attribute '__dict__'


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5644878.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存