4

有没有办法覆盖python中内置类型的特殊函数?例如,我想创建一个继承自内置 dict 的 SpecialDict 类。我想允许用户为我的特殊字典中的键和值定义自定义验证函数,如下所示:

def __init__(self, keyValidator = True, valueValidator = True):
    self.keyValidator = keyValidator
    self.valueValidator = valueValidator

使用它,我可以拦截更新方法中添加的值,如下所示:

def update(self,key,value):
    assert (self.keyValidator(key))
    assert (self.valueValidator(key))
    self[key] = value

但是,如果有人决定继续使用 [] 作为访问权限,这将不起作用。或者,如果有人使用字典文字创建对象。

mySpecialDict = SpecialDict
mySpecialDict['hello'] = 54
4

4 回答 4

4

有人无法将您的实例创建SpecialDict为字典文字,因为字典文字就是这样;一本普通的字典。

至于用方括号表示的设置项目,如mySpecialDict['hello'] = 54,仅对应于mySpecialDict.__setitem__('hello', 54)。同样,使用方括号表示法检索项目对应于方法的调用__getitem__。不管是什么阶级,这都是真的mySpecialDict;无论是普通字典、继承 builtin 的类dict,还是一些完全不相关的类。因此,您可以只实现这些方法来更改它们的功能(在需要时使用super(SpecialDict, self).__setitem__(key, value)dict.__setitem__(self, key, value)引用正常实现)。

您将遇到的一个问题是,其他 dict 方法的某些(全部?)内置实现将不尊重您覆盖的__setitem____getitem__. 所以你将无法继承它们;您必须覆盖所有这些,或者根据您的基本操作版本完全重新实现它们,或者至少“围绕”超类调用运行您的验证。

一个不那么痛苦的方法实际上可能是子类化内置字典,而是实现一个自定义的“类字典”对象,该对象包装一个普通字典,使用collections.Mappingcollections.MutableMapping基类来获取字典接口。使用这种方法,您只需要自己实现大约 6 个基本方法(您可以通过围绕对包装字典的调用插入验证逻辑来​​实现),并根据它们获得其他方法的合理定义。请参阅http://docs.python.org/library/collections.html#collections-abstract-base-classes

于 2012-05-18T00:17:12.990 回答
2

你可以重写特殊方法__getitem__来实现你自己的[]操作符行为。有关更多信息,请参阅

于 2012-05-17T22:46:37.070 回答
0

您可以覆盖__setitem__(self, key, val) 方法,并使用super(SpecialDict, self).__setitem__来访问父对象的(即dicts)方法:

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作为默认值:简单地使用TrueorFalse将导致错误,因为它们不可调用。

于 2012-05-17T22:49:55.107 回答
-1

雷!

我在移动设备中,因此无法给出完整的答案,但请查看__getitem__并查看__setitem__

于 2012-05-17T22:47:04.157 回答