2013-04-22 16 views
5

私は、インターフェイスを表す抽象基本クラスを持っています。このクラスのサブクラスは、このクラスの他のサブクラスとしてプロパティとして格納されます。例えばネストされたクラスインスタンスに便利なデフォルトの__repr__

class AbstractBase(object): 
    pass 

class Child(AbstractBase): 
    def __init__(self, cls1, cls2): 
     assert isinstance(cls1, AbstractBase) 
     assert isinstance(cls2, AbstractBase) # just to show they're instances 

     self.cls1 = cls1 
     self.cls2 = cls2 

階層の深さとレイアウトを事前に知ることはできないが、再帰的ではありません。

__repr__AbstractBaseに入れれば、どのようにして各子クラスの特色を役立てることができますか?

私の現在のアプローチがある:AbstractBaseを持つクラスのために、しかし

MyClass 
{'var1': 1, 
'var2': 2} 

:基本クラスの

from pprint import pformat 

class AbstractBase(object): 
    def __repr__(self): 
     return self.__class__.__name__ + '\n' \ 
       + pformat({k:v for k,v in self.__dict__.iteritems() 
          if not '__' in k}) 

AbstractBaseのサブクラスですがない性質で、これは例えば、読みやすい何かを出力します親クラスがどこで開始し、どこで終わるかを知るのは難しいので、サブクラスは破棄されます(上記の__repr__によってさらにネスティングのレベルがインデントされていない場合)

私は、単一のintプロパティvarcls1cls2を想像し、以下のようなものと幸せになるだろう:悲しいこと

Child 
{'cls1': { 
      'var': 1, 
     }, 
'cls2': { 
      'var': 0, 
     } 
} 

を、私はこれを達成する方法がわからない(あるいはそれも可能だ場合) 。何かご意見は?

+2

あなたがあなた自身のものをロールバックする必要がありますので、 'pformat'とそれを組み合わせるする方法はおそらくありません、といくつかの奇妙なコーナーがあるでしょうけれどもあなたは、'デフ__repr __(自己、インデント= 1) 'のような何かをしたいですあなたがカバーすることができない場合 –

答えて

2

私はこのようにそれをやってしまったものを好き:

class AbstractBase(object): 
    def __repr__(self, indent=2): 
     result = self.__class__.__name__ + '\n' 
     for k,v in self.__dict__.iteritems(): 
      if k.startswith('__'): 
       continue 
      if isinstance(v, AbstractBase): 
       vStr = v.__repr__(indent + 2) 
      else: 
       vStr = str(v) 
      result += ' '*indent + k + ': ' + vStr 
     result += '\n' 
     return result 
+0

私はこの応答が好きです。シーケンスを考慮に入れて少し修正しました。(私の考えでは)少しだけ読みやすい出力を印刷しました。私の答えを見てください。他に誰も輝きのストロークがないなら、私は数日であなたを受け入れます:) – sapi

0

これはジョンZwinckが提案されているものの少し変更したバージョンです。

シーケンスのフォーマット方法を検討し、フォーマットを少し変更します。これは完璧ではありませんが、特に、iterableコンポーネントはキーを印刷するだけなので、辞書では破棄されると思います。

def __repr__(self, indent=2): 
     result = self.__class__.__name__ + '\n' 
     items = self.__dict__.items() 

     for i,(k,v) in enumerate(items): 
      if '__' in k: 
       continue  
      if isinstance(v, AbstractBase): 
       vStr = '\n' + ' '*(indent + 2) + v.__repr__(indent + 4) 
      elif isinstance(v, collections.Iterable): 
       s = str(v) 
       bstart = s[0] 
       bend = s[-1] 

       newIndent = indent + 3 
       vStr = '\n' + ' '*(newIndent - 1) + bstart 
       for j,item in enumerate(v): 
        if isinstance(item, AbstractBase): 
         if j: 
          vStr += ' '*newIndent 
         vStr += item.__repr__(newIndent + 2) 
        else:  
         vStr += repr(item) 
        vStr += ',\n' 
       vStr += ' '*(newIndent - 1) + bend 
      else:    
       vStr = str(v) 
      result += ' '*indent + k + ': ' + vStr 

      if i != len(items) - 1: 
       result += '\n' 

     result = re.sub('\n+', '\n', result) 
     return result 
関連する問題