Python 中 UserDict 类的优点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1392396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:07:32  来源:igfitidea点击:

Advantages of UserDict class in Python

pythonoop

提问by legesh

What are advantages of using UserDictclass?

使用UserDict类的优点是什么?

I mean, what I really get if instead of

我的意思是,如果不是

class MyClass(object):
    def __init__(self):
        self.a = 0
        self.b = 0
...
m = MyClass()
m.a = 5
m.b = 7

I will write the following:

我会写以下内容:

class MyClass(UserDict):
    def __init__(self):
        UserDict.__init__(self)
        self["a"] = 0
        self["b"] = 0
...
m = MyClass()
m["a"] = 5
m["b"] = 7

Edit: If I understand right I can add new fields to an object in a runtime in both cases?

编辑:如果我理解正确,我可以在两种情况下在运行时向对象添加新字段吗?

m.c = "Cool"

and

m["c"] = "Cool"

回答by Alex Martelli

UserDict.UserDicthas no substantial added value since Python 2.2, since, as @gs mention, you can now subclass dictdirectly -- it exists only for backwards compatibility with Python 2.1 and earlier, when builtin types could not be subclasses. Still, it was kept in Python 3 (now in its proper place in the collectionsmodule) since, as the docsnow mention,

UserDict.UserDict自 Python 2.2 以来没有实质性的附加值,因为正如@gs 所提到的,您现在可以dict直接子类化——它的存在只是为了向后兼容 Python 2.1 及更早版本,当内置类型不能是子类时。尽管如此,它仍然保留在 Python 3 中(现在在collections模块中的适当位置),因为正如文档现在提到的那样,

The need for this class has been partially supplanted by the ability to subclass directly from dict; however, this class can be easier to work with because the underlying dictionary is accessible as an attribute.

对此类的需求已部分被直接从 dict 子类化的能力所取代;但是,这个类可以更容易使用,因为底层字典可以作为属性访问。

UserDict.DictMixin, in Python 2, is quite handy -- as the docs say,

UserDict.DictMixin,在 Python 2 中,非常方便——正如文档所说,

The module defines a mixin, DictMixin, defining all dictionary methods for classes that already have a minimum mapping interface. This greatly simplifies writing classes that need to be substitutable for dictionaries (such as the shelve module).

该模块定义了一个 mixin,DictMixin,为已经具有最小映射接口的类定义了所有字典方法。这大大简化了需要替换字典的类的编写(例如 shelve 模块)。

You subclass it, define some fundamental methods (at least __getitem__, which is sufficient for a read-only mapping without the ability to get keys or iterate; also keysif you need those abilities; possibly __setitem__, and you have a R/W mapping without the ability of removing items; add __delitem__for full capability, and possibly override other methods for reasons of performance), and get a full-fledged implementation of dict's rich API (update, get, and so on). A great example of the Template Methoddesign pattern.

您将其子类化,定义一些基本方法(至少__getitem__,对于没有获取键或迭代能力的只读映射来说已经足够了;keys如果您需要这些能力;可能__setitem__,并且您有一个没有能力的 R/W 映射删除项目;添加__delitem__完整功能,并可能出于性能原因覆盖其他方法),并获得dict丰富的 API(updateget等)的成熟实现。模板方法设计模式的一个很好的例子。

In Python 3, DictMixinis gone; you can get almostthe same functionality by relying on collections.MutableMappinginstead (or just collections.Mappingfor R/O mappings). It's a bit more elegant, though not QUITE as handy (see this issue, which was closed with "won't fix"; the short discussion is worth reading).

在 Python 3 中,DictMixin消失了;您可以通过依赖(或仅用于 R/O 映射)来获得几乎相同的功能。它更优雅一点,虽然不是很方便(参见这个问题,它以“不会修复”结束;简短的讨论值得一读)。collections.MutableMappingcollections.Mapping

回答by Georg Sch?lly

Subclassing the dict gives you all the features of a dict, like if x in dict:. You normally do this if you want to extend the features of the dict, creating an ordered dict for example.

对 dict 进行子类化可为您提供 dict 的所有功能,例如if x in dict:. 如果您想扩展 dict 的功能,您通常会这样做,例如创建一个有序的 dict。

BTW: In more recent Python versions you can subclass dictdirectly, you don't need UserDict.

顺便说一句:在最近的 Python 版本中,您可以dict直接子类化,您不需要UserDict.

回答by JL Peyret

Well, as of 3.6 there are certainly some disadvantages, as I just found out. Namely, isinstance(o, dict)returns False.

好吧,正如我刚刚发现的那样,从 3.6 开始,肯定有一些缺点。即,isinstance(o, dict)返回 False。

    from collections import UserDict

    class MyClass(UserDict):
        pass

    data = MyClass(a=1,b=2)

    print("a:", data.get("a"))
    print("is it a dict?:", isinstance(data, dict))

Not a dict!

不是字典!

a: 1
is it a dict?: False

Change to class MyClass(dict):and isinstancereturns True.

更改为class MyClass(dict):isinstance返回 True。

However... with UserDict you can step into its implementation.

但是......使用 UserDict 您可以进入它的实现。

(pdb-ing into functions/methods is an easy way to see exactly how they work)

(pdb-ing 到函数/方法是一种简单的方法来查看它们是如何工作的)


#assumes UserDict

di = MyClass()

import pdb

#pdb will have work if your ancestor is UserDict, but not with dict
#since it is c-based
pdb.set_trace()
di["a"]= 1