我编写了一个继承dict builtin类型的python类。我想用其他检查方法编写一种容器。
如果我创建该类的实例,我得到了一个RecursionError。我不明白这个错误。
class Params(dict):
""" A convenient container of all paramters """
# list of authorized keywords with default values
keywords = {"k1": 1, "k2": 2, "k3": 3}
def __init__(self, *args, **kwargs):
# self.update(self.keywords)
for k, v in self.keywords.items():
self[k] = v
self.update(*args, **kwargs)
def update(self, *args, **kwargs):
for k, v in dict(*args, **kwargs).items():
self[k] = v
def __setitem__(self, name, value):
""" set a parameters following dict syntax """
name = name.lower()
if name in self.keywords:
self[name] = value
else:
raise KeyError("Keywords %s does not exist." % name)
def __getattr__(self, name):
""" get paramters as an attribute of the class """
return self.__getitem__(name)
答案 0 :(得分:1)
因此,正如我在评论中暗示的那样,您的递归错误正在发生,因为您在self.__setitem__
中隐含地调用self.__setitem__
,因此您应该调用超类 {{1相反。这是一种方式:
__setitem__
注意,我使用了{3}的Python 3版本
Python 2需要:In [6]: class Params(dict):
...: """ A convenient container of all paramters """
...:
...: # list of authorized keywords with default values
...: keywords = {"k1": 1, "k2": 2, "k3": 3}
...:
...: def __init__(self, *args, **kwargs):
...: # self.update(self.keywords)
...: for k, v in self.keywords.items():
...: self[k] = v
...: self.update(*args, **kwargs)
...:
...: def update(self, *args, **kwargs):
...: for k, v in dict(*args, **kwargs).items():
...: self[k] = v
...:
...: def __setitem__(self, name, value):
...: """ set a parameters following dict syntax """
...: name = name.lower()
...: if name in self.keywords:
...: # note: dict.__setitem__(self, name, value) would also work
...: super().__setitem__(name, value)
...: else:
...: raise KeyError("Keywords %s does not exist." % name)
...:
...: def __getattr__(self, name):
...: """ get paramters as an attribute of the class """
...: return self.__getitem__(name)
...:
In [7]: p = Params(k1=10)
In [8]: p
Out[8]: {'k1': 10, 'k2': 2, 'k3': 3}
注意,一般来说,我更喜欢组合而不是继承。拥有一个super
对象,其中包含您通过公共接口管理的内部super(Params, self).__setitem__(name, value)
属性。这将更加强大,并避免继承内置类型带来的麻烦。