我想知道class(dict)和class(str)之间存在什么样的差异 这是我的代码
class MyDict3(str):
def __init__(self):
self.a = None
class MyDict(dict):
def __init__(self):
self.a = None
这些类是我为澄清而做的 然后我在下面输入
>>> 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
为什么我的mydict3 ['a']会出错? 我所做的不同只是MyDict(dict)和MyDict(str) 据我所知,我指定的对象(dict,str)只不过像c ++,java这样的构造函数
请给我一个明确的答案。
答案 0 :(得分:0)
为什么我的mydict3 [&#39; a&#39;]会出错?我所做的差异只有MyDict(dict)和MyDict(str)据我所知,我指定的对象(dict,str)只不过是像c ++,java
这样的构造函数。
我相信你在这里做了一个混乱,认为一个类属性和一个项目是一样的,就像下面的javascript代码一样:
> foo = {'a': 42};
{ a: 42 }
> foo.a
42
> foo['a']
42
> foo.a === foo['a']
true
但是在python中foo.a
和foo['a']
是两种不同的机制。当您致电foo.a
时,您实际上正在访问通过类定义定义的类的a
属性:
class Foo:
def __init__(self):
self.a = 42 # declaring and defining the a attribute
然后您可以使用以下方式访问它:
>>> foo = Foo()
>>> print(foo.a)
42
但要使foo['a']
正常工作,您必须使用索引机制,该机制通常用于词典或列表:
>>> foo = {'a': 42}
>>> foo['a']
42
该机制正由您班级的__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'
因此,dict
类是一个实现__getitem__
(和__setitem__
以及许多其他类)的类,以便为您提供称为字典的正确映射机制。键可以是任何不可变对象,并且值可以是任何值。对于列表,它应该只是整数(列表中的位置)。
话虽如此,让我们回答你的问题:
为什么我的mydict3 [&#39; a&#39;]会出错?
显然它是因为你将mydict3
定义为字符串的实现,它具有__getitem__
方法的特殊实现:它为你提供了一个字符参数位置,如果列表是一个字符列表(如在C中)。
因此,当您尝试使用mydict3
索引'a'
时,python只会告诉您,您所要求的内容毫无意义!
所以最后,当你说:
它实际上是一个非常大的差异!我所做的不同只是MyDict(dict)和MyDict(str)
dict
和str
没有相同的界面,因此您想要做的事情无法发挥作用!
P.S。:实际上,没有什么是黑色或白色。一个类的实现实际上是一个dict,你可以访问一个类的所有成员&#39;实例通过实例的__dict__
成员:
class Foo():
def __init__(self):
self.a = 42
>>> foo = Foo()
>>> foo.__dict__['a']
42
但您永远不会直接直接访问__dict__
实例,并使用辅助函数setattr
和getattr
:
>>> setattr(foo, 'b', 42)
>>> getattr(foo, 'b')
42
>>> getattr(foo, 'a')
42
这是一些高级的python技巧,应谨慎使用。如果真的 没有别的办法,那么也许你应该使用它。
此外,还有一个特殊的类将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