Reputation: 31
Here is my code:
class StrKeyDict(dict):
def __init__(self):
super().__init__()
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return self[str(key)]
def __contains__(self, key):
return key in self.keys() or str(key) in self.keys()
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default
if __name__ == "__main__":
d = StrKeyDict([('2', 'two'), ('4', "four")])
I want to inherit the build-in dict, so I use super(). But when I use StrKeyDict([('2', 'two'), ('4', "four")])
to initialize it, error comes like this:
Traceback (most recent call last):
File "/Users/nick/PyProjects/Fluent-Python/3-6.py", line 25, in <module>
d = StrKeyDict([('2', 'two'), ('4', "four")])
TypeError: __init__() takes 1 positional argument but 2 were given
However, if I delete __init__()
the whole class will work just fine. So my question is:
super().__init__()
a must in every class?super().__init__()
, how would I modify?Upvotes: 0
Views: 918
Reputation: 33127
Is
super().__init__()
a must in every class?
No, you only need it when you want to run the inherited __init__
and do something extra, like only allowing certain parameters, or further mutating self
afterwards.
In this case, where StrKeyDict.__init__()
doesn't do anything extra, you should remove it and let StrKeyDict
inherit dict.__init__()
.
If I want to keep
super().__init__()
, how would I modify?
You would need StrKeyDict.__init__()
to take arguments and pass them to super().__init__()
.
If you want to be permissive/lazy, you can allow anything:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Or if you want to be restrictive, match the signature of dict.__init__()
:
def __init__(self, mapping_or_iterable, **kwargs):
super().__init__(mapping_or_iterable, **kwargs)
P.S. I've let out some nuances here, but this should be enough to get you on your way.
Upvotes: 1
Reputation: 440
Here is rectified code:
class StrKeyDict(dict):
def __init__(self,lst):
super().__init__(lst)
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return self[str(key)]
def __contains__(self, key):
return key in self.keys() or str(key) in self.keys()
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default
if __name__ == "__main__":
d = StrKeyDict([('2', 'two'), ('4', "four")])
Upvotes: 0
Reputation: 2153
The error is raised because your call to create a StrKeyDict
passed in the array and you did not allow for it in __init__
's parameters. it should have been:
def __init__(self, my_list):
...
etc
Upvotes: 1
Reputation: 342
By doing this class StrKeyDict(dict):
you inherit dict, there is no need for init unless you want to initialize something when the class is created.
Upvotes: 2