[英]python the difference between class(dict) and class(str)
I am wondering what kind of difference exists between class(dict) and class(str) Here is my code 我想知道class(dict)和class(str)之间存在什么区别这是我的代码
class MyDict3(str):
def __init__(self):
self.a = None
class MyDict(dict):
def __init__(self):
self.a = None
These classes are what I made for clarification and then I type below 这些类是我为澄清而编写的,然后在下面键入
>>> mydict['a'] = 1
>>> mydict
{'a': 1}
>>> mydict3['a'] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'MyDict3' object does not support item assignment
Why does my mydict3['a'] make an error? 为什么mydict3 ['a']出错了? The difference that I made is only MyDict(dict) and MyDict(str) As far as I know, the object that I specified(dict, str) is just nothing but constructer like c++,java 我所做的只是MyDict(dict)和MyDict(str)据我所知,我指定的对象(dict,str)只是c ++,java之类的构造方法
Please give me a clear answer on that. 请给我一个明确的答案。
Why does my mydict3['a'] make an error? 为什么mydict3 ['a']出错了? The difference that I made is only MyDict(dict) and MyDict(str) As far as I know, the object that I specified(dict, str) is just nothing but constructer like c++,java 我所做的只是MyDict(dict)和MyDict(str)据我所知,我指定的对象(dict,str)只是c ++,java之类的构造方法
I believe that you're doing a confusion here, thinking that a class attribute and an item are the same thing, like the following javascript code: 我认为您在这里感到困惑,认为类属性和项目是同一件事,例如以下javascript代码:
> foo = {'a': 42};
{ a: 42 }
> foo.a
42
> foo['a']
42
> foo.a === foo['a']
true
But in python foo.a
and foo['a']
are two different mechanisms. 但是在python中, foo.a
和foo['a']
是两种不同的机制。 When you call foo.a
you're actually accessing the a
attribute of a class, which is defined through the class definition: 调用foo.a
,实际上是在访问通过类定义定义的类的a
属性:
class Foo:
def __init__(self):
self.a = 42 # declaring and defining the a attribute
so then you can access it using: 因此,您可以使用以下命令访问它:
>>> foo = Foo()
>>> print(foo.a)
42
But to have foo['a']
working, you have to use the indexing mechanism, which is usually used for dicts or lists: 但是foo['a']
有效,您必须使用索引机制,该机制通常用于字典或列表:
>>> foo = {'a': 42}
>>> foo['a']
42
That mechanism is being implemented by the __getitem__
method of your class, so you can overload it if you want: 该机制由您的类的__getitem__
方法实现,因此您可以根据需要重载它:
class Foo:
def __getitem__(self, val):
if val == 'a':
return 42
raise KeyError('Unknown key') # when the key is unknown, you raise a key error exception
>>> foo = Foo()
>>> foo['a']
42
>>> foo['b']
KeyError: 'Unknown key'
So, the dict
class is a class that implements __getitem__
(and __setitem__
and many others), in order to provide you a proper mapping mechanism called a dictionary. 因此, dict
类是实现__getitem__
(和__setitem__
以及其他许多类)的类,以便为您提供称为字典的适当映射机制。 There keys can be any immutable objects, and values anything. 键可以是任何不可变的对象,并且值可以是任何值。 For a list, it shall be only integers (which are the positions in the list). 对于列表,只能是整数(即列表中的位置)。
That being said, let's answer your question: 话虽如此,让我们回答您的问题:
Why does my mydict3['a'] make an error? 为什么mydict3 ['a']出错了?
obviously it's because you defined mydict3
as being an implementation of a string, which has a special implementation for the __getitem__
method: it's giving you a character at the parameter position like if the list was a list of character (like in C). 显然,这是因为您将mydict3
定义为字符串的实现,该字符串对__getitem__
方法具有特殊的实现:它在参数位置处为您提供了一个字符,就像列表是字符列表一样(如C语言)。
So when you're trying to index mydict3
with 'a'
, python just tells you that what you're asking makes no sense! 因此,当您尝试使用'a'
为mydict3
编制索引时,python只会告诉您您的要求没有任何意义!
So in the end, when you say: 所以最后,当您说:
The difference that I made is only MyDict(dict) and MyDict(str) 我所做的只是MyDict(dict)和MyDict(str)
it's actually a very big difference! 实际上有很大的不同! A dict
and an str
do not have the same interface, and thus what you want to do cannot work! dict
和str
没有相同的接口,因此您想执行的操作不起作用!
PS: Actually, nothing is black or white. PS:实际上,没有什么是黑色或白色的。 The implementation of a class actually is a dict, and you can access all members of a class' instance through the __dict__
member of an instance: 类的实现实际上是一个dict,您可以通过实例的__dict__
成员访问该类实例的所有成员:
class Foo():
def __init__(self):
self.a = 42
>>> foo = Foo()
>>> foo.__dict__['a']
42
but you shall never directly access the __dict__
instance directly, and use helper functions setattr
and getattr
: 但是您绝不能直接直接访问__dict__
实例,并使用辅助函数setattr
和getattr
:
>>> setattr(foo, 'b', 42)
>>> getattr(foo, 'b')
42
>>> getattr(foo, 'a')
42
This is some advanced python tricks, and they should be use with care. 这是一些高级的python技巧,应谨慎使用。 If there's really no other way to do it, then maybe you should use that. 如果确实没有其他方法可以这样做,那么也许您应该使用它。
Also, there exists a special class that transform dict items as class members, it's the namedtuple
: 另外,有一个特殊的类将dict项转换为类成员,即namedtuple
:
>>> from collections import namedtuple
>>> d = {'a': 42, 'b': 69}
>>> SpecialDict = namedtuple('SpecialDict', d.keys())
>>> foo = SpecialDict(**d)
>>> d.a
42
>>> d.b
69
HTH 高温超导
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.