4

シーケンスタイプに=を割り当てるためのPythonマジックメソッド__setitem__があります。 コンテナレベルで追加の割り当て+=のための魔法の方法がありますか?操作は、項目タイプの拡張された割り当てに正常に分類されているように見えます。それは論理的です。しかし、他のほとんどすべてのための魔法の方法があります、私はシーケンスの型でこれらの演算子のためのメソッドのセットがあるはずだと思った。私はそれを見逃しましたか?`self [key] + = value`のマジックメソッド?

アプリケーションは一種のデータベースです。 SELECTで__getitem__を実装し、INSERTで__setitem__を実装すると考えてください。 UPDATEには__additem__などが必要でしょうか?

from __future__ import print_function 
class Item(object): 
    def __init__(self, value): 
     self.value = value 
    def __str__(self): 
     return "Item " + str(self.value) 
    def __iadd__(self, other): 
     print("Item iadd", self, other) 
     return Item(self.value + "+" + other.value) 

class Container(object): 
    def __getitem__(self, key): 
     print("Container getitem", key) 
     return Item(key) 
    def __setitem__(self, key, value): 
     print("Container setitem", key, value) 
     return self 
    def __additem__(self, key, value): 
     print("Container additem would be nice", key, value) 
     return self 

は、ここで選択します:

>>> c = Container() 
>>> _ = c['key'] 
Container getitem key 

ここでINSERTです:

>>> c['key'] = Item('other') 
Container setitem key Item other 

UPDATEを実装する方法は?分解せずにSELECTとINSERT:

>>> c['key'] += Item('other') 
Container getitem key 
Item iadd Item key Item other 
Container setitem key Item key+other 

だから、壊れた手順とは異なる累算代入を実装する方法はありますか? Itemクラスにすべての振る舞いを入れないで?


あなたはカット&ペースト上記のコードをPythonインタプリタへ、またはこのPythonのフィドルでそれを試すことができます。 http://pythonfiddle.com/add-item-for-sequence/


related questionいいえ、ありますself[key] += value

答えて

3

の逆コンパイルを示していますいいえ魔法__additem__メソッド。

c[k] += vは、魔法の呼び出し:c.__setitem__(c.__getitem__(k).__iadd__(v))に変わります。

__setitem__呼び出しが含まれているのは、すべてのPythonオブジェクトがインプレース追加をサポートしているわけではないからです。変更できないオブジェクト(intおよびfloatなど)はありません。__iadd__の代わりに__add__が呼び出されます(また、__add__に新しい値を返す必要があります)。

私はあなたが望むようにデータベースを動作させる唯一の方法は、特別な「アイテムプロキシ」タイプを返すように__getitem__と書いていると思います。プロキシは最初は何もしません(独自の振る舞いはありません)。しかし、属性またはメソッドが参照されると(または__magic__メソッドが呼び出されたとき)、それは機能するために必要なデータベース操作を行います。ほとんどのメソッドおよび属性ルックアップでは、実際のデータを取得するためにデータベースにクエリを行い、適切なメソッドまたは値を返す必要があります。それはのような(appendまたは__iadd__と呼ばれていた知られているインプレース修正の方法であった場合、それは代わりに別のデータベース操作を行うことができます(代わりにSELECTUPDATE)。

なプロキシタイプを書くように非常にではありませんあなたは多くの種類のオブジェクトを扱いたいと思っていたら、たくさんのコーナーケースがあります。データベースが保持できるタイプの範囲に応じて、プロキシがほんの数個に複製するのに必要なメソッドと属性のリストを絞り込むことができます(例:算術演算子と比較演算子、__int____float__数値型のみをサポートする必要があります)。

一方、コードが少なくてSELECTINSERTを行うことができれば、開発には手間がかかりません。

関連する問題