有没有办法在python中覆盖内置类型的特殊函数?例如,我想创建一个继承自内置字典的SpecialDict类。我想允许用户为我的特殊字典中的键和值定义自定义验证函数,如下所示:
def __init__(self, keyValidator = True, valueValidator = True):
self.keyValidator = keyValidator
self.valueValidator = valueValidator
使用它,我可以拦截update方法中的值的添加,如下所示:
def update(self,key,value):
assert (self.keyValidator(key))
assert (self.valueValidator(key))
self[key] = value
但如果有人决定继续使用[]作为访问权限,那么这将无效。或者,如果有人使用字典文字创建对象。
mySpecialDict = SpecialDict
mySpecialDict['hello'] = 54
答案 0 :(得分:4)
有人无法创建SpecialDict
的实例作为字典文字,因为字典文字就是这样;正常的字典。
使用方括号表示法设置项目,如mySpecialDict['hello'] = 54
中那样,只对应mySpecialDict.__setitem__('hello', 54)
。同样,使用方括号表示法检索项目对应于__getitem__
方法的调用。无论班级mySpecialDict
是什么,都是如此;它是普通字典,是内置dict
的子类,还是一些完全不相关的类。因此,您可以实现这些方法来更改他们的操作(在需要时使用super(SpecialDict, self).__setitem__(key, value)
或dict.__setitem__(self, key, value)
引用正常实现)。
您将遇到的一个问题是,其他dict方法的内置实现中的某些(全部?)将不会尊重被覆盖的__setitem__
或__getitem__
。所以你将无法继承它们;您必须覆盖所有这些,并根据您的基本操作版本完全重新实现它们,或者至少在超类调用“周围”运行验证。
一个不太痛苦的方法实际上可能是不子类化内置字典,而是实现一个自定义的“类似dict”的对象包装一个普通的字典,使用获取字典界面的collections.Mapping
或collections.MutableMapping
基类。使用这种方法,您只需要自己实现大约6种基本方法(通过围绕对包装字典的调用插入验证逻辑),并根据它们获得其他方法的合理定义。见http://docs.python.org/library/collections.html#collections-abstract-base-classes
答案 1 :(得分:2)
您可以覆盖特殊方法__getitem__
以实现您自己的[]
运算符行为。有关详细信息,请参阅this。
答案 2 :(得分:0)
雷!
我在移动设备中,因此无法提供完整的答案,但请查看__getitem__
和__setitem__
答案 3 :(得分:0)
您可以覆盖__setitem__(self, key, val)
方法,并使用super(SpecialDict, self).__setitem__
访问父对象(即dict
s)方法:
class SpecialDict(dict):
def __init__(self, keyValidator = lambda x:True, valueValidator = lambda x:True):
self.keyValidator = keyValidator
self.valueValidator = valueValidator
def __setitem__(self, key, val):
assert (self.keyValidator(key))
assert (self.valueValidator(val))
super(SpecialDict, self).__setitem__(key, val)
另请注意,使用lambdas作为默认值:仅使用True
或False
会导致错误,因为它们无法调用。