2013-04-22 1 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 

계층의 깊이와 레이아웃을 미리 알 수 없지만, 재귀 없습니다.

AbstractBase에 입력하면 유용한 방법으로 각 하위 클래스의 소유권을 볼 수 있습니다.

내 현재의 접근 방식은 다음과 같습니다

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

그러나, 클래스 AbstractBase과 : AbstractBase의 서브 클래스 프로퍼티가

기본 클래스에 대한
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}) 

는 (이 읽을 것을, 예를 출력 하위 클래스는 부모 클래스가 시작하고 다른 클래스가 시작되는 곳을 말하기 어렵 기 때문에 (중첩의 추가 수준은 위의 __repr__에 들여 쓰기가 추가되지 않음)

내가 cls1cls2이 단일의 int 속성 var했다 상상, 아래와 같은 뭔가 드리겠습니다 : 슬프게도

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

을, 나는 이것을 달성하는 방법을 알고 (또는 심지어 가능하다면)하지 않는다 . 이견있는 사람?

+2

당신은 뭔가를 원하는'데프 __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 구성 요소는 키만 인쇄하기 때문에 사전에 문제가 있다고 생각합니다. 거기에 당신의 자신의 롤 그래서 pformat` '와 결합 할 수있는 방법은 아마하지 않으며, 비록

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