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
Advantages of UserDict class in Python
提问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.UserDict
has no substantial added value since Python 2.2, since, as @gs mention, you can now subclass dict
directly -- 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 collections
module) 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 keys
if 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(update
、get
等)的成熟实现。模板方法设计模式的一个很好的例子。
In Python 3, DictMixin
is gone; you can get almostthe same functionality by relying on collections.MutableMapping
instead (or just collections.Mapping
for 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.MutableMapping
collections.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 dict
directly, 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 isinstance
returns 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