Why does my mydict3['a'] make an error? 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
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:
> 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. When you call foo.a you're actually accessing the a attribute of a class, which is defined through the class definition:
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': 42}
>>> foo['a']
42
That mechanism is being implemented by the __getitem__ method of your class, so you can overload it if you want:
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. 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?
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).
So when you're trying to index mydict3 with 'a', python just tells you that what you're asking makes no sense!
So in the end, when you say:
The difference that I made is only MyDict(dict) and 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!
P.S.: Actually, nothing is black or white. 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:
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:
>>> 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. 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:
>>> from collections import namedtuple
>>> d = {'a': 42, 'b': 69}
>>> SpecialDict = namedtuple('SpecialDict', d.keys())
>>> foo = SpecialDict(**d)
>>> d.a
42
>>> d.b
69
HTH