1

このコードを 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」は書き込み可能ではありません

4

1 に答える 1

3

次の 2 行を置き換える必要があると思います。

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では、 のコンストラクターは引数iterablecollections.dequeを 1 つしか取りませんでした:

deque([iterable])

そのため、オブジェクトを初期化した後にmaxlenを設定する必要がありました。

Python 2.6では、オプションの引数としてmaxlenを指定できました。

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

これはPython 3.4でも同じままです。コンストラクタ引数として設定することは、2.6 以降の推奨されるアプローチだったと思います。彼らは下位互換性を壊したくなかったので、2.x シリーズであなたのアプローチ (属性を直接設定する) を取り除くことができませんでした。

Python 3 ではそのような懸念はなく、コンストラクター引数を使用することが唯一の方法でした。


サイドノート

空のリストで初期化してからユーザー提供の utterable で拡張するのではなく、その iterable をcollections.deque直接渡してみませんか? すなわち

super(TailDeque, self).__init__(iterable, maxlen=maxlen)
于 2016-02-11T19:57:48.483 に答える