258 ー 6 章オブジェクト指向プログラミング の init メソッドはオーバライドする必要があり、そうしなければこのレシピは意味がなくなってしまう。 幸いにも thon は親クラスの初期化コードを勝手に実行したりはしないので、コピー元オプジェクトのクラ スの init メソッドはこのオーバライドによって実行されなくなる。 こうして目的のクラスの「空」オプジェクトを作ったら、たいていはコピー元から self へと、属性の一部 をコピーする必要がある。もしすべての属性をコピーしたいのであれば、一 copy ーメソッドを明示的に定義 するのはよそう。すべてのインスタンス属性をコピーするのは copy. copy のデフォルト動作だからだ。もちろ ん、ただすべての属性をコピーするのでなく、コピーした後でいろいろな操作を行うというなら、全属性を コピーする以下の 2 つのテクニックが便利だ・ . update(self. dict_) = dict(self. dict_) ただ、新スタイルのクラスでは dict にすべてのオプジェクト状態が入っているとは限らない。これに あてはまるクラスでは状態コピーを行わねばならないだろう。 標準ライプラリモジュール new を使った方法もあるが、新旧のクラススタイルを同じように扱うことができ ないし、これは空のインスタンスを生成する静的メソッド new でも無理だ。 new は新スタイルクラス でしか定義されていないのだ。レシピの方法であればこういった問題は解決されている。 他にも良い方法がある。ー ( opy ーメソッドを実装する代わりに getstate メソッドと setstate メソッ ドを実装するのだ。これらの特殊メソッドは明示的にオプジェクトの状態を外部とやり取りするためのもの で、本質的に init_ メソッドをバイバスしている。加えて、この getstate メソッドと setstate メ ソッドは、クラスインスタンスのシリアライズ ( pi 〔 kle 化 ) をサポートしている。詳しくは「レシピ 7.4 クラス、 インスタンスでの cPickle の使用」を参照してほしい。 こまで多くの場合に使われるシャローコピーについて議論をしてきた。シャローコピーはオプジェ さて、 クト自体をコピーするが、そのオプジェクトから参照される属性やシーケンス要素についてはコピーせず、コ ピー元オプジェクトと同じものを参照するので処理が速くて軽い。一方、ディープコピーは、複雑に絡み合っ たオプジェクト参照グラフを複製しなければならないこともある重い処理だ。ディープコピーは copy ・ deepcopy 関数で行うことができる。作成したクラスのインスタンスをディープコピーで複製するときの動作をカスタ マイズしたい場合は特殊メソッド _deepcopy_ を定義する。 newcopy. _dict newcopy ・ dict class YourClass(0bject) : def _deepcopy_(self, memo) : newcopy = empty copy(self) # copy. deepcopy(self. x, memo) を使い、 self の属性の要素のうち # 適切なものだけを newcopy にディープコピーする return newcopy deep ( opy ーを実装する場合は、 thon の標準モジュールドキュメントにも書かれている memoization プロ トコルのことも考慮することーーー属性やアイテムのディープコピーをとる際に呼び出す copy. deepcopy の第 2 deepcopy_ メソッドに渡されたディクショナリそのものを渡さなければならない。ディー 引数には、
6. IO カべージコレクションを邪魔することなく結合メソッドへのリファレンスを保持ー 259 プコピーにおいても _getstate メソッドや setstate メソッドの実装は有効な代案である。これらのメ ソッドはディープコピーをサポートしている。つまり、 Python はディープコピーの際に _getstate メソッ ドの返す状態オプジェクトをディープコピーし、新しい空インスタンスの setstate メソッドに渡すのだ。 両メソッドの詳細については「レシピ 7.4 クラス、インスタンスでの cPickle の使用」を参照してほしい。 参照 シャローコピーおよびディープコピーについては、「レシピ 4 . 1 オプジェクトのコピー」を参照、 getstate および setstate メソッドについては「レシピ 7.4 クラス、インスタンスでの cPickIe の使 用」を参照。ライプラリリファレンスおよび fPython クイックリファレンス』の copy モジュールの節。 6.10 ガべージコレクションを邪魔することなく 結合メソッドへのリファレンスを保持 Credit: Joseph A. Knapka, Frdric Jolliton, Nicodemus 訳 : 鴨澤眞夫、吉田聡 問題 結合メソッドへの参照は保持したいが、結合元オブジェクトのガべージコレクションが可能な形 で行いたい。 解法 弱参照 ( 他に通常の参照がなければオプジェクトを維持しないオプジェクト参照 ) は、ある種の高度なプロ グラミングでとても重要な道具となる。弱参照は thon 標準ライプラリに含まれる weak て ef モジュールを呼 び出せば使うことができる。 しかし、 weakref モジュールはそのままでは結合メソッドに適用できない。結合メソッドへの参照の有無に かかわらすオプジェクトをカべージコレクションできるようにするには、ある種のラッパーが必要である。 weakmethod. py というファイル名で次のコードを保存し、 sys. path のどこかに置けば、このラッパークラスが 使える : import weakref, new class ref(object): コーラブル、特に結合メソッドを、結合メソッドのオプジェクトが ガべージコレクト可能な形でラップする。このとき通常の弱参照と同じ インタフェースを提供する。 init_(self, (n) : try: # 引数値がオブジェクト、関数、クラスの属性値を持つか調べる 0 , f, ( = fn. im self, fn. im func, fn. im class def except AttributeError: self. 0bj = None # 持たない場合は結合メソッドではない
6.6 p 「 oxy で特殊メソッドを委譲ー 251 考察 プロキシやメソッドの自動委譲は、 Python では _getattr メソッドがあるおかげで楽に書くことができ る。 thon は属性 ( ここで言う属性にはメソッドも含まれる。 thon では属性とメソッドは区別しない ) の参 照を行ってうまくいかなかった場合、 getattr メソッドを自動的に呼び出す。 getattr は特殊メソッドに対しても通常どおりに適用された。これは 従来のオプジェクトモデルでは、 注意しないと、せんぜん追加したくない特殊メソッドを誤って提供してしまうことにもつながるのだが、そ れ以外はます便利なものである。現在、新規に書くコードについては新しいスタイルのオプジェクトのみを 使うことが推奨されている。こちらの方が高速で正規的で機能も豊富なのだ ( 新スタイルのクラスは、 object またはビルトイン型のいすれかを継承することで得ることができる ) 。いつの日か、これから何年か後には、 thon3.0 が従来のオプジェクトモデルを排除することになっている。これは後方互換性のためにのみ存在 する他の機能についても同じだ ( 詳細は http://www.python.org/peps/pep-3000.html を参照。 Python 3.0 のプ ランの詳細が書かれている。そのほとんどは新しい機能というよりは Python という言語をよりシンプルにす るための変更である ) 。 新しいスタイルのオプジェクトモデルでは、 thon は実行時に特殊メソッドの検索を行わす、クラスオプ ジェクトに用意された「スロット」のみを参照する。スロットはクラスオプジェクトが作成または修正され たときのみ更新される。このため、ラッピングしたオプジェクトに特殊メソッドを委譲したいプロキシオプ ジェクトは、それ専用に仕立てあげたクラスに属している必要がある。幸いなことに、レシピで示した通り、 クラスを実行時に生成してインスタンス化するのは Python ではとても簡単である。 このレシピでは、メタクラスやディスクリプタのカスタマイズといった高度な Python の概念は使わない。 その代わりプロキシを作成するファクトリ関数 proxy を使っている。このファクトリ関数の引数では、ラップ されるオプジェクトと、プロキシで扱う特殊メソッドの名前を指定する ( 特殊メソッド名の前後のアンダース コア記号は取り除いて指定する ) 。「解法」で示したコードを proxy. py というファイルにして Python のパス ( sys. path ) の中に置けば、 thon のインタラクテイプモードから次のようにしてプロキシオプジェクトを使 うことができる : 〉〉〉 import proxy = proxy. proxy([ ] , 'iter') # 'len' > > 〉 a. 0bj く class proxy. listProxy ・〉 class く proxy. listProxy 0bject at 0X0113 ( 370 〉 len repr と iter のみを委譲 は委譲されていない > > > a. append # 特殊メソッドではないメソッドはすべて委譲されている く built-in method append 0 十 list 0bject at 0X010FIA10 〉 len ーメソッドは委譲されているので、 len ( a ) は予想通りの動作をする。 0
索引 609 printf 関数… .. 187 print 文 .. random モジュール . … 427 raw_input 関数 .. PriorityQueue クラス . … 367 Privacy-enhanced Electronic M ail (PEM) . readLines メソッド . ... 596 procmail.. read メソッド . … 412 referenceError 例外 .. progressbar クラス . … 429 pr 叩 erty 関数 .. ref クラス . … 255 proxy 関数 .. repeat メソッド . … 251 psycopg モジュール . replace メソッド … 318 pty モジュール .. resource 、モジ、ユーーノレ … 395 re モジュール Py-DBAPI (Python DB Application Programming サプシーケンスを見つける . lnterface) . … 295 PyGTK インタフェース .. 複数パターンの置換 .. … 428 文字列処理… PyGUI API.. … 428 pysqlite モジュール . →正規表現も参照 … 324 Python . rfc822 モジュール . … 232 ActivePython . rjust メソッド . … 330 C の prin ば関数 .. .. 187 RPC (Remote Procedure Call) . C ライプラリ . rrule. count メソッド … 361 OOP 機構 .. rstrip メソッド … 231 オプジェクトツリー … 479 加算器… .. 144 簡潔さ .. … 231 ショートカット . .. 151-192 マルチスレッドプログラミング .. … 360 , 361 リレーショナルデータベースと ~ ... 295 巧 rthon 2.3 .. decimal モジュール . 文字の詰め込み .. 文字列中の変数… 巧 rthon 2.4 .. doctest モジュール . DSU サポート .. email ノヾーーヨガーー ジェネレーショ ン式 .. メールメッセー ン .. 文字の詰め込み .. 文字列中の変数… Python Database Row モジュ ール Python lmaging Library (PIL) . Pythonwin ツールキット . PyWin32 パッケージ . PyXML パッケージ .. .. 188 … 427 … 59 , 64 .. 59 , 64 , 302 , 497 … 261 … 259 … 235 … 52 , 67 … 340 … 223 … 39 … 409 ... 571 .. 123 s. isdigit メソッド s. toupper メソッド . sanitise 関数 .. … 509 SAX.. … 473 , 488 SAX API.. … 471 sched モジュール . .. 136 Secure Socket Layer (SSL) .. … 524 seek メソッド . … 59 , 75 select メソッド . ... 216 select モジュール . … 389 , 572 self. something 構文 . .. 233 ド .. serve forever メソッ … 579 setdefault メソッド . .. 169 sets モジュール . … 98 , 182 Set 型 .. .. 182 set メソッド . .. 18 shebang ( # ! ) .. … 67 shelve モジュール . ... 309 SimpIeXMLRPCServer モジュール .... 572 , 573 , 580 Singleton デザインパターン . … 232 , 274 Borg クラスの利用 .. .. 276 SMTP (Simple Mail Transfer Protocol) . … 493 sn 叩 shOt メソッド … 267 SNTP (Simplified Network Time Protocol) . … 499 SOAP (SimpIe Object Access ProtocoI) . … 572 LO 1 LO -4 1 っ 0 … 353 … 201 … 509 .. 176 … 509 … 35-38 ... 324 … 439 … 428 … 330 , 396 … 471 … 361 , 367 , 369 … 444 Queue クラス . GUI..
スーバークラスの 6.1 9 class L00kBeforeYouLeap(), Y, Z) : init_(self) : def class bases base. init_(self) init if hasattr(base, fo て base in self. この方法をもっと汎用的に、 init 以外のメソッドにも適用し、 . サブクラス LookBeforeYouLeap 固有の初期化処理を行う . init が存在すれば実行する ー 287 インスタンスやクラスに指定したメソッ ドが存在する場合にのみこれを呼び出したい、という場合は少なくない。つまり、呼び出したいメソッドが クラスやインスタンスに存在しなければ何もせず、存在すれば、何かしら行動を起こすという場合である。 「解法」に挙げた、ビルトイン super を使用する方法は、このような場合に汎用的に適用できない。これは、 現在のオプジェクトのスーパークラスが適切に super を使用しており、問題になるメソッドがスーパークラス に存在する場合にしか適用できないのだ。新スタイルのクラスはすべて init メソッドを持っことに注意 してほしい。これらはすべて obje ( t のサプクラスであり、 object は init_ メソッドを ( 何もせず、渡され た引数をすべて無視するという関数として ) 定義している。したがって全ての新スタイルクラスが、継承また init メソッドを持っていることになる。 はオーバーライドにより、 一方 L00kBeforeYouLeap クラスのやり方は汎用性が高いので、 init 以外のメソッドの場合にも役に立つ。 実のところ、このやり方は super と一緒に使うこともできる : class Base1(0bject) : def met(self) : print 'met in Base1' class Der1(BaseI) : def met(self) : = super(Der1, self) S if hasattr(), 'met'): s. met( ) print ・ met in Der1 ' class Base2(0bject): paSS class Der2(Base2): def met(self) : = super(Der2, self) S if hasattr(), 'met ・ ): s. met( ) print 'met in De て 2 ・ Der1( ). met( ) Der2( ) ・ met( ) このコードは以下のように出力する :
260 ー Clas = None 考察 cf = (. f del cf 6 章 オブジェクト指向プログラミング self. self. else: self. else. if 0 func = fn is None: self. obj = None ・ self. obj = weakref. ref(o) self. func = f Clas def call_(self): # 持つ場合は結合メソッドである # 実は「非」結合だった場合 # ちゃんと結合してる場合 if self. obj is None: return self. func elif self. obj( ) is None: return None return new. instancemethod(self. func, self. 0bj( ) , self. clas) ぎり、オプジェクトをガべージコレクションで破棄することはできない・ 通常の結合メソッドは、オプジェクトへの強い参照を保持している。だから結合メソッドを破棄しないか class C(0bject): print " 〔 dying' def del_(self) : print " He110 " def f(self) : del ( ( dying # ( は虚ろな目でさまよい続けるのだ . # ... その結合メソッドを串刺しにするまでは。これで ( は死ぬ : この振る舞いは便利だが、ときにそれを望まないこともある。たとえばイベントディスパッチシステムを 実装する場合、イベントハンドラ ( すなわち結合メソッド ) がただ存在するだけで、結合元のオプジェクトを 再利用できないようでは困ってしまう。直観的には、弱参照を使えばこの問題が解決できると思うかもしれ ない。ところが weakref. ref で結合メソッドに弱参照を行っても、思ったとおりには動かない。これは結合メ ソッドが独立したファーストクラスオプジェクトだからである。このため結合メソッドへの弱参照は、作っ た途端に dead になってしまう。つまり他に強い参照がない限り、すでに破棄されたオプジェクトへの参照と みなされ、常に None を返すのである。 たとえば、次のように weakref モジュールを使った場合、 None は関数呼び出しできないという例外が発生し てしまう。 cf = weakref. ref(). f) import weakref cf # うぬ、もっと電撃が必要だな。おいアイゴール・
234 ー 6 章オブジェクト指向プログラミング thon はこれらの特殊メソッドをコールする。たとえば len ( x ) は x. len ー ( ) を、 a + b は通常 a. add_(b) を、 getitem (b) を返す。ということはつまり、特殊メソッドを定義することで、インスタンスに数 a[b] は a. 値、リスト、ディクショナリといったビルトイン型オプジェクトとの互換性を持たせられるのだ。 ーフ してこれらの関数やオペレーションに与えられた重要な付加価値である。 供される特殊メソッド間の固有構造は、 someobje ( t. somemethod ( 引数 ) といった純粋 OO な表記を尊重 、で、オブジェクト b にもこの件に関する発言権を与える。こうした演算やビルトイン関数により提 ます a. ー add ( b ) を試行するが、これがうまくいかなければ続いて b. ー radd ーー ( a ) を試行すること 演算やビルトイン関数は、特殊メソッド群を一定の順序で試行しうる。たとえば a + b という演算は とがポリモーフィズムのおかげで可能なのだ。では Behave クラスの他に、 repeat メソッドがちょっと違った オプジェクトに対し同じメソッドをコールしつつ、メソッドの実装はオプジェクトごとに異なる、というこ 異なったオプジェクトを類似の方法で扱う能力、ポリモーフィズムは、 OOP の大きな利点だ。さまざまな for whatever in aMix: whatever. repeat(3) aMiX = beehive, Behave('J0hn' ) , Repeater( ) , Behave( 'world' ) repeat メソッドのみをコールする限り、 Behave と Repeate てのインスタンスは一緒にできる : def repeat(self, N) : print N*"*-*" class Repeater(0bject) : ふるまいをするクラスも作っておこう : おいてクラスと関数のテンプレートで実現される種類のもの ) に非常に似たプログラミングスタイルを、でき だけでよい。シグネチャ・べースのポリモーフィズムは汎用プログラミング ( genericprogramming 。 C + + に 式な定義と実装が必要だ。 thon では同じシグネチャの ( つまり同じ名前で同じ引数を取る ) メソッドを作る こうしたポリモーフィズムの実現には、他の言語では継承 ( インヘリタンス ) すなわちインタフェースの正 sublnstance. repeat(3) sublnstance = Subc1ass("Queen Bee") def once(self) : print ' (%s) ' % self. name class Subc1ass(Behave) : イド ) するのである。 のクラスから継承することでクラス定義を行い ( サプクラス化 ) 、メソッドを付け加えたり再定義 ( オーバ thon では継承も使える。これはだいたいにおいて手軽でエレガントで構造的なコード再利用法である。他 の悪い構文や複雑な概念をともなわす可能にする。 ソッドの本体はインスタンスに対し once を n 回コールする。インスタンスが持つ once メソッドの正体は斟酌 メソッドがコールできる。 Subclass が Behave スーパークラスからこれを継承しているからである。 repeat メ クラス Subclass は once メソッドをオーバーライドしているだけだが、そのインスタンス sublnstance は repeat
6.9 オブジェクトのコピーを素早く ー 257 CIass newcopy ・ return newcopy class empty_copy 関数は、次のようにクラスの class YourClass(0bject) : init_(self) : def -COPY- メソッドをするのに使う : # ここにはインスタンスを初期化する比較的長いコードが入っている def _copy_(self) : newcopy = empty_copy(self) # ここには self から一部の属性だけを newcopy にコピーするコードが入っている 使い方は以下のようになる : return newcopy if name maln import copy y = YourClass( ) print y = copy ・ copy(y) Z print z 考察 init init メソッドが実行される メソッドは実行されない 「レシピ 4.1 オプジェクトのコピー」のレシピが示すように、 python は代入によって暗黙のうちにオプジェ クトをコピーすることはない。コピーしないほうが高速かっ柔軟性があり、構文上の一貫性を持たせられる といったメリットがある。もしオプジェクトのコピーを行うのであれば、明示的に copy. ( opy 関数を使って行 う必要がある。 ( opy. copy 関数は、ビルトイン型であればどのようにコピーを行うか知っており、新しく作っ たクラスオプジェクトについても適切なデフォルトのコピー方法を用意し、また特殊メソッドー ( opy ーを用 意すればコピー方法をカスタマイズすることもできる。もしクラスインスタンスをコピー禁止にしたいので あれば一 copy ーメソッドの中で TypeE Ⅱ or 例外を起こせばよい。通常 ( opy ・ ( opy 関数のデフォルトのコピーメ カニズムに任せれば、自分で書いたクラスも自由なコピーが可能となる。プログラミング言語によっては、イ ンスタンスをコピー可能にするため、クラスごとにクローン用のメソッドを実装しなければならないものも あるが、それに比べたら thon のコピーメカニズムはとても便利な仕組みである。 init メソッドがハイコストなため、 _copy_ メソッドで当該のクラス ( つまり self) の「空」インスタ ンスをます作ることでこれをバイバスしたい場合も多い。もっともシンプルで汎用的な方法は、 thon がイ ンスタンスのクラスを動的に変更できることを利用するものである。つまりこのレシピのように、空のイン スタンスを作るためのクラスをローカルに用意してそのクラスで新しいオプジェクトを作り、その class 属性を差し替えてしまう方法である。空のインスタンスを作る Empty クラスが、コピーしようとするオプジェ クトのクラス obj. class から継承する部分は ( 無害ではあるものの ) 古いスタイルのクラスにおいては冗長 な書き方かもしれない。しかしこの継承によって、このレシピは新旧両方のクラススタイルで ( しかもビルト イン型・拡張型の両方で ) 動作することが可能になっている。 obj. class の継承を行う場合、 Empty クラス
506 ー if 考察 ] 3 章ネットワークプログラミング if name = = None: ・ part-%i" % partCounter name = partCounter + = 1 # 実際には name があなたの OS で使えるファイル名であることを # 確認し、そうでない場合は縮めるなりすること f = open(name, "wb") f. write(part. get_payload(decode=l)) f. close( ) print name maln name main( ) email パッケージを使えば MIME メッセージのパースも容易い。このレシピでは email パッケージのメッ セージオプジェクトにある walk メソッドを使い、 MIME メッセージをアンバンドルする方法を示した。 メッセージオプジェクトはいろいろな方法で生成できる。たとえば email. Message. Message クラスのインス タンス化を行い、できたメッセージオプジェクトのメソッドをコールして内容を構築する方法がある。しか しこのレシピでは既存のメッセージを読み込んで分析する必要があるので、他の方法、すなわち email. parser. parser インスタンスの p 訂 se メソッドを使った。 parse メソッドは唯一の引数としてファイル的 オプジェクト ( レシピではビルトイン関数叩 en によりバイナリ読込みで開いた真のファイルオプジェクトを渡 した ) を取り、戻り値としてメッセージオプジェクトを返すので、これにメッセージオプジェクトのメソッド がコールできる。 walk メソッドはジェネレータである ( つまり、 f0 て文でループできる反復子オプジェクトを返す ) 。 walk メ ソッドは、レシピで示したこのやり方で使うのが普通だ・ fo て part in msg ・ walk( ) : この反復子は、メッセージを構成する各パートをシーケンシャルに ( ネストしている場合は深度順に ) 返す。 メッセージがパートのコンテナじゃない ( 添付がない、つまり message. is multipart が false を返す ) って ? 大丈夫。この場合 walk メソッドは単一の要素ーーメッセージそのもの一一一を持つ反復子を返す。どんな場合 でも反復子の各要素はまたメッセージオプジェクト (email. Message. Message のインスタンス ) でもあるので、 メッセージオプジェクトのメソッドがコールできる。 マルチパートメッセージには、 multipart/nantyara のタイプを持っ ( つまりメインタイプが multipart である ) パートが存在しうる。レシピではこれを明示的にスキップした。これらは真のパートを固めるニカワにすぎ ーでは get main type メソッドでメインタイプを取り、これが ' multipart ' に等しいかをチェッ ないからだ クし、等しければ continue 文でスキップして次のパートに移るようにした。真のパートが手に入ったときは 名前を特定し ( パートが名無しなら合成し ) 、その名前でファイルを開き、メッセージ内容 ( メッセージのペイ ロード、ともいう ) を get payload メソッドのコールによって取得して書き込む。必要な場合は引数 decode = 1 を 使い、ペイロードがテキストのままでなくバイナリ ( イメージ、サウンド、ムービーなど ) にデコードし直さ れることを保証した。ペイロードがエンコードされていなかったとしても decode=l は無害なので、引数を渡
264 ー 6 章オブジェクト指向プログラー self. max = SIZe max self. data = def full_append(self, x) : self. data[self. cur] = x ニング ( 011e ( tion. deque 型を継承して作ることも考えてみるべきだ。この型は先頭と末尾に対して効率的に要素を付 リングバッフアを実装する方法は他にも色々ある。特に p y t h 0 n 2.4 を使っているのであれば、 ンスではなく、クラスを対象に行われるからだ ( 旧スタイルのクラスではそうではない ) 。 を変更するしかない。クラスに色々な操作が加えられている場合、特殊メソッドのルックアップはインスタ ドを変更する方法をとるとよい。だが、新スタイルのクラスで、特殊メソッドを変更したいときにはクラス ある際には、クラスを変更する方法を使用し、振る舞いをちょっとだけ変更しさえすればよい場合にはメソッ る方法と同じである。もっとも効果的なアプローチとしては、全てのメソッドの振る舞いを変更する必要が このメソッドを変更する方法は、仕組みはちょっと違うが、本質的にはレシピで紹介したクラスを変更す return self. data def tolist(self) : self. tolist = self. full_get self. append = self. full append # に不可逆に変更 # バッフアが満杯じゃない場合のメソッドから満杯時のメソッド self. cur = 0 if len(self. data) = = self. max: self. data. append(x) def append(self, x) : return self. data[self. cur: ] + self. data[ :self. cur] def full_get(self) : self. cur = ( self. ( u て + 1 ) % self. max と組み合わせて使うこともできる。 満杯状態になったかどうか、毎回 if 文でチェックするのを避けたいのであれば、メソッドを変更する方法 return list(self) def tolist(self): self. popleft( ) if len(self) > self. size max: deque. append(self, datum) def append(self, datum) : self. Size max = Size max deque. init_(self) def init (self, size max) : class RingBuffer(deque) : from collections import deque け加えたり、削除することのできる「両端キュー」をサポートしている。