Python类转换实现环形队列

本文介绍如何使用Python创建一个固定大小的环形队列,当队列满时,新元素将覆盖最早添加的元素,常用于日志存储。通过类转换技巧,当环填满时,改变类的行为,实现高效且无性能损失的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义一个固定大小的缓存,当它被填满时,新加入的元素自动覆盖第一个元素,这种方法经常用在存储日志和历史信息的程序中。


[root@xiaoxiong cb6]# cat cb2_6_11_sol_1.py 
class RingBuffer(object):
    """ class that implements a not-yet-full buffer """
    def __init__(self, size_max):
        self.max = size_max
        self.data = []
    class __Full(object):
        """ class that implements a full buffer """
        def append(self, x):
            """ Append an element overwriting the oldest one. """
            self.data[self.cur] = x
            self.cur = (self.cur+1) % self.max
        def tolist(self):
            """ return list of elements in correct order. """
            return self.data[self.cur:] + self.data[:self.cur]
    def append(self, x):
        """ append an element at the end of the buffer. """
        self.data.append(x)
        if len(self.data) == self.max:
            self.cur = 0
            #当队列满时将self的类从非满改为满
            self.__class__ = self.__Full
    def tolist(self):
        """ Return a list of elements from the oldest to the newest. """
        return self.data
# sample usage
if __name__ == '__main__':
    x = RingBuffer(5)
    x.append(1); x.append(2); x.append(3); x.append(4)
    print x.__class__, x.tolist()
    x.append(5)
    print x.__class__, x.tolist()
    x.append(6)
    print x.data, x.tolist()
    x.append(7); x.append(8); x.append(9); x.append(10)
    print x.data, x.tolist()
[root@xiaoxiong cb6]# 
[root@xiaoxiong cb6]# python cb2_6_11_sol_1.py 
<class '__main__.RingBuffer'> [1, 2, 3, 4]
<class '__main__.__Full'> [1, 2, 3, 4, 5]
[6, 2, 3, 4, 5] [2, 3, 4, 5, 6]
[6, 7, 8, 9, 10] [6, 7, 8, 9, 10]
[root@xiaoxiong cb6]# 

值得注意的地方是,我通过修改self.__class__来完成这种转变:
self.__class__ = self.__Full

当环填满时,给__class__赋值以改变其行为方式,这种切换类的方法效率非常高,这种类转换是一次性的操作,所以它不会带来任何性能上的开销。可以参考下文通过切换实例方法来实现的技巧。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值