使用Mixins扩展类功能
程序员文章站
2023-12-22 00:02:40
...
-
可以有很多的方法,来扩展其他类的功能。如果这些类并没有任何继承的关系。 因此你不能简单的将这些方法放入一个基类,然后被其他类继承。
-
通常当你想自定义类的时候会碰上这些问题。可能是某个库提供了一些基础类, 你可以利用它们来构造你自己的类。
-
可以使用扩展映射对象,给它们添加日志、唯一性设置、类型检查等等功能。
from collections import defaultdict
class Log_Mapping_Extension(object):
"""
Add logging to get/set/delete operations for debugging.
"""
__slots__ = ()
def __getitem__(self, key):
print('Getting ' + str(key))
return super().__getitem__(key)
def __setitem__(self, key, value):
print('Setting {} = {!r}'.format(key, value))
return super().__setitem__(key, value)
def __delitem__(self, key):
print('Deleting ' + str(key))
return super().__delitem__(key)
class A_Collection_Mapping_Extension(object):
'''
Only allow a key to be set once.
'''
__slots__ = ()
def __setitem__(self, key, value):
if key in self:
raise KeyError(str(key) + ' already set')
return super().__setitem__(key, value)
class StringKeysMappingMixin:
'''
Restrict keys to strings only
'''
__slots__ = ()
def __setitem__(self, key, value):
if not isinstance(key, str):
raise TypeError('keys must be strings')
return super().__setitem__(key, value)
class LogDict(Log_Mapping_Extension, dict):
pass
class A_Collection_Mapping_ExtensionDict(A_Collection_Mapping_Extension, defaultdict):
pass
if __name__ == "__main__":
d = LogDict()
d['x'] = 23
d["y"] = 46
print(d['x'])
print(d)
del d['x']
d = A_Collection_Mapping_ExtensionDict(list)
d['x'].append(6)
d['x'].append(12)
print(d["x"])
这些类不能被单独实例化,它们是用来通过多继承来和其他映射对象混入使用的。