覆盖Python中的特殊功能

时间:2012-05-17 22:36:27

标签: python inheritance

有没有办法在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

4 个答案:

答案 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.Mappingcollections.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作为默认值:仅使用TrueFalse会导致错误,因为它们无法调用。