2011-11-15 5 views
1

私は非常に大規模なネストされた辞書で主に構成されたオブジェクトがあります。__str__とプリティプリント(サブ)辞書

class my_object(object): 
    def __init__(self): 
     self.the_dict = {} # Big, nested dictionary 

を私が変更した__単純でトップレベルの辞書をかなり-印刷するstr__ 「印刷」対象:

print(the_object) # Pretty-prints entire dict 
:ここ

def __str__(self): 
     pp = pprint.PrettyPrinter() 
     return pp.pformat(self.the_dict) 

私の目標は、彼/彼女はIPythonを持つオブジェクトを閲覧する際、ユーザーの生活が少し楽にすることでした

は、これが全体の辞書をユーザに示すために動作しますが、私は、ユーザーのようなコマンドからきれいに印刷出力を取得することができ、同様の辞書のサブ部分には、この機能を拡張したいと思います:

print(the_object.the_dict['level1']['level2']['level3']) 

( 'level3' sub-dictのみがきれいに印刷されます)

これを行うには__ str__などを使用する簡単な方法はありますか?

答えて

1

あなたは、対話型プロンプトであなたの好みに合わせてお選び組み込み辞書やその他のオブジェクトを出力するカスタムのdisplayhookを提供することができます:

>>> import sys 
>>> oldhook = sys.displayhook 
>>> sys.displayhook = your_module.DisplayHook(oldhook) 

それはprint obj動作を変更しません。

ユーザーはdictのカスタム書式を使用するかどうかをユーザーが選択できるという考えがあります。

+0

シャイニー!この機能に精通していない。これはスピンを与えるだろう。ありがとう! –

0

あなたはこのような何かがどうなるかもしれない...基礎となる辞書に「きれいな印刷辞書を」変換できます

class my_object(object): 
    _pp = pprint.PrettyPrinter() 

    class PP_dict(dict): 
     def __setitem__(self, key, value): 
      if isinstance(value, dict): value = PP_dict(value) 
      super(my_object.PP_dict, self).__setitem__(key, value) 

     def __str__(self): 
      return my_object.pp(self) 

    @property 
    def the_dict(self): 
     return self.__dict__[ 'the_dict' ] 

    @the_dict.setter 
    def the_dict(self, value): 
     self.__dict__[ 'the_dict' ] = my_object.PP_dict(value) 

プロパティは、「私はあなたが操作/設定方法を知らないだけであるためであるthe_dict "

このアプローチは限られている - 例えば、あなたがthe_dictでdictsではありませんdictの誘導体を置けば、彼らはPP_dictによって置き換えられます。あなたはこれらのsubdictsへの他の参照を持っている場合にも、彼らはもはや、同じオブジェクトを指していることはありません。

別のアプローチは、かなり__str__に現在のオブジェクトを印刷した辞書のプロキシラッパーを返し__getitem__直接my_objectをで、置くことであろうがサブオブジェクトのためのプロキシを返すように__getitem__をオーバーライドし、へのそれ以外すべて転送acccess /操作ラップされたクラス。

1

ユーザーはPythonがthe_object.the_dict['level1']['level2']['level3']を評価し、それを辞書であり、その上printにを渡し見つかっ(さんが言わせて)

print(the_object.the_dict['level1']['level2']['level3']) 

を言います。 the_object.the_dict以来

は辞書で、残りはthe_objectのコントロール外です。あなたがlevel1level2、およびlevel3を下穴を掘ると、the_object.the_dict['level1']['level2']['level3']によって返されるオブジェクトの唯一のタイプはどのように振る舞うprintに影響を与えるために起こっています。 the_object__str__方法はthe_object自体を超えて何も影響を及ぼしするつもりはありません。

さらに、ネストされたオブジェクトを印刷する場合、pprint.pformatはオブジェクトのreprではなくstrを使用します。

だから我々が望む振る舞いを得るために、私たちは辞書のように、異なる__repr__で何かに評価するthe_object.the_dict['level1']['level2']['level3']が必要...


あなたは辞書のようなオブジェクトを作ることができる(例えば、Turtle)とすべての方法ダウンTurtlesを使用します。

import collections 
import pprint 

class Turtle(collections.MutableMapping): 
    def __init__(self,*args,**kwargs): 
     self._data=dict(*args,**kwargs) 
    def __getitem__(self,key): 
     return self._data[key] 
    def __setitem__(self, key, value): 
     self._data[key]=value 
    def __delitem__(self, key): 
     del self._data[key] 
    def __iter__(self): 
     return iter(self._data) 
    def __len__(self): 
     return len(self._data) 
    def __contains__(self, x): 
     return x in self._data 
    def __repr__(self): 
     return pprint.pformat(self._data) 

class MyObject(object): 
    def __init__(self): 
     self.the_dict=Turtle() 
    def __repr__(self): 
     return repr(self.the_dict) 

the_object=MyObject() 
the_object.the_dict['level1']=Turtle() 
the_object.the_dict['level1']['level2']=Turtle() 
the_object.the_dict['level1']['level2']['level3']=Turtle({i:i for i in range(20)}) 
print(the_object) 
print(the_object.the_dict['level1']['level2']['level3']) 

これを使用するには、Turtle Sを使用して、ネストされた辞書構造内のすべてのdictsを交換する必要があります。

実際には(私の虚構な名前からわかるように)、私は実際にTurtleを使用するとは思っていません。 Dictsは素敵で最適化された組み込み関数なので、私はこの中間オブジェクトを追加するだけで、きれいな印刷ができます。代わりにあなたが

from pprint import pprint 

を入力するユーザーを納得させることができる場合

その後、彼らはただ

pprint(the_object.the_dict['level1']['level2']['level3']) 

はかなり印刷を取得するために使用することができます。

+0

良好なロジックです。私は同じ結論に達しました。ありがとう! –