简体   繁体   English

python class(dict)和class(s​​tr)之间的区别

[英]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(s​​tr)之间存在什么区别这是我的代码

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.afoo['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! dictstr没有相同的接口,因此您想执行的操作不起作用!


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__实例,并使用辅助函数setattrgetattr

>>> 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM