Stack Overflow Asked by Nick Yang on December 13, 2021
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?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.
Answered by wjandrea on December 13, 2021
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")])
Answered by TheSohan on December 13, 2021
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
Answered by LhasaDad on December 13, 2021
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.
Answered by Crapy on December 13, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP