一个类似于 dict 的 python 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4014621/
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
A python class that acts like dict
提问by skyeagle
I want to write a custom class that behaves like dict- so, I am inheriting from dict.
我想编写一个行为类似于的自定义类dict- 所以,我继承自dict.
My question, though, is: Do I need to create a private dictmember in my __init__()method?. I don't see the point of this, since I already have the dictbehavior if I simply inherit from dict.
不过,我的问题是:我需要dict在我的__init__()方法中创建一个私有成员吗?。我不明白这有什么意义,因为dict如果我只是从dict.
Can anyone point out why most of the inheritance snippets look like the one below?
谁能指出为什么大多数继承片段看起来像下面的片段?
class CustomDictOne(dict):
def __init__(self):
self._mydict = {}
# other methods follow
Instead of the simpler...
而不是更简单的...
class CustomDictTwo(dict):
def __init__(self):
# initialize my other stuff here ...
# other methods follow
Actually, I think I suspect the answer to the question is so that users cannot directly access your dictionary (i.e. they have to use the access methods that you have provided).
实际上,我认为我怀疑问题的答案是用户无法直接访问您的字典(即他们必须使用您提供的访问方法)。
However, what about the array access operator []? How would one implement that? So far, I have not seen an example that shows how to override the []operator.
但是,数组访问运算符[]呢?如何实现呢?到目前为止,我还没有看到显示如何覆盖[]运算符的示例。
So if a []access function is not provided in the custom class, the inherited base methods will be operating on a different dictionary?
那么如果[]自定义类中没有提供访问函数,继承的基方法将在不同的字典上运行?
I tried the following snippet to test out my understanding of Python inheritance:
我尝试了以下代码段来测试我对 Python 继承的理解:
class myDict(dict):
def __init__(self):
self._dict = {}
def add(self, id, val):
self._dict[id] = val
md = myDict()
md.add('id', 123)
print md[id]
I got the following error:
我收到以下错误:
KeyError: < built-in function id>
KeyError: <内置函数 id>
What is wrong with the code above?
上面的代码有什么问题?
How do I correct the class myDictso that I can write code like this?
如何更正课程myDict以便我可以编写这样的代码?
md = myDict()
md['id'] = 123
[Edit]
[编辑]
I have edited the code sample above to get rid of the silly error I made before I dashed away from my desk. It was a typo (I should have spotted it from the error message).
我已经编辑了上面的代码示例,以消除我在冲离办公桌之前犯的愚蠢错误。这是一个错字(我应该从错误消息中发现它)。
采纳答案by Bj?rn Pollex
Check the documentation on emulating container types. In your case, the first parameter to addshould be self.
查看有关模拟容器类型的文档。在你的情况下,第一个参数add应该是self.
回答by bgporter
The problem with this chunk of code:
这段代码的问题:
class myDict(dict):
def __init__(self):
self._dict = {}
def add(id, val):
self._dict[id] = val
md = myDict()
md.add('id', 123)
...is that your 'add' method (...and any method you want to be a member of a class) needs to have an explicit 'self' declared as its first argument, like:
...是您的“add”方法(...以及您想成为类成员的任何方法)需要将显式“self”声明为它的第一个参数,例如:
def add(self, 'id', 23):
To implement the operator overloading to access items by key, look in the docsfor the magic methods __getitem__and __setitem__.
要实现运算符重载以通过键访问项目,请查看文档中的魔术方法__getitem__和__setitem__.
Note that because Python uses Duck Typing, there may actually be no reason to derive your custom dict class from the language's dict class -- without knowing more about what you're trying to do (e.g, if you need to pass an instance of this class into some code someplace that will break unless isinstance(MyDict(), dict) == True), you may be better off just implementing the API that makes your class sufficiently dict-like and stopping there.
请注意,因为 Python 使用 Duck Typing,所以实际上可能没有理由从语言的 dict 类派生您的自定义 dict 类——而不知道更多关于您要做什么的信息(例如,如果您需要传递 this 的一个实例)类到某个地方的代码中,除非isinstance(MyDict(), dict) == True),否则您最好只实现 API,使您的类足够像 dict 并在那里停止。
回答by S.Lott
Like this
像这样
class CustomDictOne(dict):
def __init__(self,*arg,**kw):
super(CustomDictOne, self).__init__(*arg, **kw)
Now you can use the built-in functions, like dict.get()as self.get().
现在您可以使用内置函数,例如dict.get()as self.get()。
You do not need to wrap a hidden self._dict. Your class already isa dict.
您不需要包装隐藏的self._dict. 你的班级已经是一个字典。
回答by Ricky Wilson
class Mapping(dict):
def __setitem__(self, key, item):
self.__dict__[key] = item
def __getitem__(self, key):
return self.__dict__[key]
def __repr__(self):
return repr(self.__dict__)
def __len__(self):
return len(self.__dict__)
def __delitem__(self, key):
del self.__dict__[key]
def clear(self):
return self.__dict__.clear()
def copy(self):
return self.__dict__.copy()
def has_key(self, k):
return k in self.__dict__
def update(self, *args, **kwargs):
return self.__dict__.update(*args, **kwargs)
def keys(self):
return self.__dict__.keys()
def values(self):
return self.__dict__.values()
def items(self):
return self.__dict__.items()
def pop(self, *args):
return self.__dict__.pop(*args)
def __cmp__(self, dict_):
return self.__cmp__(self.__dict__, dict_)
def __contains__(self, item):
return item in self.__dict__
def __iter__(self):
return iter(self.__dict__)
def __unicode__(self):
return unicode(repr(self.__dict__))
o = Mapping()
o.foo = "bar"
o['lumberHyman'] = 'foo'
o.update({'a': 'b'}, c=44)
print 'lumberHyman' in o
print o
In [187]: run mapping.py
True
{'a': 'b', 'lumberHyman': 'foo', 'foo': 'bar', 'c': 44}
回答by he1ix
For the sake of completeness, here is the link to the documentation mentioned by @bj?rn-pollex for the latest Python 2.x (2.7.7 as of the time of writing):
为了完整起见,这里是@bj?rn-pollex 提到的最新 Python 2.x(截至撰写本文时为 2.7.7)文档的链接:
(Sorry for not using the comments function, I'm just not allowed to do so by stackoverflow.)
(抱歉没有使用评论功能,我只是不允许 stackoverflow 这样做。)
回答by user2674414
Don't inherit from Python built-in dict, ever! for example updatemethod woldn't use __setitem__, they do a lot for optimization. Use UserDict.
永远不要从 Python 内置 dict 继承!例如update方法不会使用__setitem__,他们做了很多优化。使用用户字典。
from collections import UserDict
class MyDict(UserDict):
def __delitem__(self, key):
pass
def __setitem__(self, key, value):
pass
回答by u6089746
Here is an alternative solution:
这是一个替代解决方案:
class AttrDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__dict__ = self
a = AttrDict()
a.a = 1
a.b = 2
回答by Danny Meijer
I really don't see the right answer to this anywhere
我真的在任何地方都看不到正确答案
class MyClass(dict):
def __init__(self, a_property):
self[a_property] = a_property
All you are really having to do is define your own __init__- that really is all that there is too it.
你真正需要做的就是定义你自己的__init__——这就是它的全部。
Another example (little more complex):
另一个例子(稍微复杂一点):
class MyClass(dict):
def __init__(self, planet):
self[planet] = planet
info = self.do_something_that_returns_a_dict()
if info:
for k, v in info.items():
self[k] = v
def do_something_that_returns_a_dict(self):
return {"mercury": "venus, "mars": "jupiter}
This last example is handy when you are wanting to embed some kind of logic.
当您想要嵌入某种逻辑时,最后一个示例非常方便。
Anyway... in short class GiveYourClassAName(dict)is enough to make your class act like a dict. Any dict operation you do on selfwill be just like a regular dict.
无论如何......总之class GiveYourClassAName(dict)足以让你的班级表现得像一个字典。您执行的任何 dict 操作都self将与常规 dict 一样。
回答by madogan
This is my best solution. I used this many times.
这是我最好的解决方案。我多次使用这个。
class DictLikeClass:
def __init__(self):
super(DictLikeClass, self).__init__()
def __getitem__(self, key):
return getattr(self, key)
def __setitem__(self, key, value):
setattr(self, key, value)
You can use like:
你可以使用像:
>>> d = DictLikeClass()
>>> d["key"] = "value"
>>> print(d["key"])

