开发者社区> 问答> 正文

利用Mixins扩展类功能

你有很多有用的方法,想使用它们来扩展其他类的功能。但是这些类并没有任何继承的关系。 因此你不能简单的将这些方法放入一个基类,然后被其他类继承。

展开
收起
哦哦喔 2020-04-17 15:07:51 1131 0
1 条回答
写回答
取消 提交回答
  • 通常当你想自定义类的时候会碰上这些问题。可能是某个库提供了一些基础类, 你可以利用它们来构造你自己的类。
    
    假设你想扩展映射对象,给它们添加日志、唯一性设置、类型检查等等功能。下面是一些混入类:
    
    class LoggedMappingMixin:
        """
        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 SetOnceMappingMixin:
        '''
        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 LoggedDict(LoggedMappingMixin, dict):
        pass
    
    d = LoggedDict()
    d['x'] = 23
    print(d['x'])
    del d['x']
    
    from collections import defaultdict
    
    class SetOnceDefaultDict(SetOnceMappingMixin, defaultdict):
        pass
    
    
    d = SetOnceDefaultDict(list)
    d['x'].append(2)
    d['x'].append(3)
    # d['x'] = 23  # KeyError: 'x already set'
    这个例子中,可以看到混入类跟其他已存在的类(比如dict、defaultdict和OrderedDict)结合起来使用,一个接一个。 结合后就能发挥正常功效了。
    
    2020-04-17 15:08:00
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
继承与功能组合 立即下载
ui-model,跨框架复用 立即下载
用RxSwift写易维护易读的愉悦代码 立即下载