如何使用Python 2.5到3.4中的collections.deque移植此代码?

时间:2016-02-11 18:21:06

标签: python python-3.x python-2.5 python-collections

如何将此代码从2.5版本移植到3.4版?

from __future__ import with_statement
from ..globals import addonPath
import os, time
import collections

class TailDeque(collections.deque):
    '''Implementation of deque with limited maxlen support for Python 2.5.'''
    def __init__(self, iterable=None, maxlen=20):
        super(TailDeque, self).__init__([])
        self.maxlen = maxlen
        if iterable is not None:
            self.extend(iterable)

    def extend(self, iterable):
        for item in iterable:
            self.append(item)

    def extendleft(self, iterable):
        for item in iterable:
            self.appendleft(item)

    def appendleft(self, item):
        if len(self) == self.maxlen:
            self.pop()
        super(TailDeque, self).appendleft(item)    

    def append(self, item):
        if len(self) == self.maxlen:
            self.popleft()
        super(TailDeque, self).append(item)

logPath = os.path.join( addonPath, "log.txt" )
logQueue = TailDeque()
def log(text):
    return
    logQueue.append(time.strftime("%H:%M:%S") + " - " + text)
    with open(logPath, "w") as fs:
        fs.write('\n'.join(logQueue))

第10行:     self.maxlen = maxlen

AttributeError:'collections.deque'对象的属性'maxlen'不可写

1 个答案:

答案 0 :(得分:3)

我认为你需要替换这两行:

super(TailDeque, self).__init__([])
self.maxlen = maxlen

使用:

if sys.version_info <= (2, 5):
    super(TailDeque, self).__init__([])
    self.maxlen = maxlen
else:
    super(TailDeque, self).__init__([], maxlen=maxlen)

如果您不需要保持与Python 2.5的兼容性,那么您可以更简单一些:

super(TailDeque, self).__init__([], maxlen=maxlen)

动机

Python 2.5中,collections.deque的构造函数只接受了一个参数, iterable

deque([iterable])

所以你必须在初始化对象后设置 maxlen

Python 2.6中,您可以提供 maxlen 作为可选参数:

collections.deque([iterable[, maxlen]])

这保持不变into Python 3.4。我认为将其设置为构造函数参数是从2.6开始的首选方法。他们无法在2.x系列中删除你的方法 - 直接设置属性,因为他们不想破坏向后兼容性。

使用Python 3,没有这样的问题,因此使用构造函数参数成为您可以使用的唯一方法。

旁注

为什么不直接将该迭代传递给collections.deque,而不是使用空列表初始化然后使用用户提供的uptrable进行扩展?即。

super(TailDeque, self).__init__(iterable, maxlen=maxlen)