2017-01-11 13 views
1

https://mail.python.org/pipermail/python-ideas/2014-September/029310.html정규 수업

에 namedtuple의 __str__ 및 __repr__ 동작을 가져와 나는 항상 namedtuple 내장 __str__을 생각 __repr__은 매우 단정했고, 난 쉽게 내 모든 클래스에 적용하는 간단한 방법을 찾고 있어요.

>>> from collections import namedtuple 
>>> A = namedtuple("A", ["foo"]) 
>>> print(A(foo=1)) 
A(foo=1) 
>>> str(A(foo=1)) 
'A(foo=1)' 
>>> repr(A(foo=1)) 
'A(foo=1)' 

편집 :

나는 처음 __repr__을, 동적이지, 긴 하드 코딩의 무리와 함께 시작했다. 나는 그것을 좋아하지 않는다. namedtuple가 멋지게 자동으로 실행됩니다.

def __repr__(self): 
    return 'className(attrA={attrA}, attrB={attrB})'.format(**vars(self))) 
+0

당신은 namedtuple 구현하는 방법을 볼 수 있습니다 https://hg.python.org/cpython/file/2.7/Lib/ collections.py # l247 – jonrsharpe

답변

5

A는 해키 비트 만이 그것을 수행합니다

from collections import namedtuple 

def nice_repr(obj): 
    def nice_repr(self): 
     return repr(
      namedtuple(
       type(self).__name__, 
       vars(self) 
      )(**vars(self)) 
     ) 

    obj.__repr__ = nice_repr 

    return obj 

예 :

@nice_repr 
class A: 
    def __init__(self, b, c): 
     self.b = b 
     self.c = c 

print(repr(A(1, 2))) # Outputs: A(c=2, b=1) 

편집 : (안전 장치 버전)

def nice_repr(obj): 
    """ Decorator to bring namedtuple's __repr__ behavior to regular classes. """ 

    def nice_repr(self): 
     v = vars(self) 

     # Prevent infinite looping if `vars` happens to include `self`. 
     del(v['self']) 

     return repr(namedtuple(type(self).__name__, v)(**v)) 

    obj.__repr__ = nice_repr 

    return obj 
+1

실제로 그것은 너무 많은 해킹이며 그처럼 사소한 일에 대한 가치가 없습니다. 클래스의'__repr__'과'__str__' 함수 선언은 모두 필요했습니다. –

+0

@MoinuddinQuadri 그리고 수동으로 매번 복사/붙여 넣기를합니까? Meh ... 나는 지나칠 것이다. 또는 하드 코드, meh 너무! – JeromeJ

+0

이 repr 구현은'namedtuple' (이는 불변이고'eval (repr (a)) == a'와 같은 일반적인 불변 조건을 만족시킬 수 있습니다)에 대해 어느 정도 의미가 있습니다. 하지만 얼마나 많은 속성을 가진 커스텀 클래스를 정의해야 하는가? 우리는 이미 대부분의 유스 케이스에 대한 데이터 구조를 가지고있다. – wim

-1

을 ~을 창조하다 "A는 : 값"당신은 당신처럼 자신의 __str__ 함수를 정의 Y 클래스는이 인쇄됩니다

class Foo: 
    def __init__(self): 
     self.a="value" 

    def __str__(self): 
     return "a is: "+self.a 

variable=Foo() 
print variable 

__init__ 기능 생성, 당신이 어떤 클래스

+0

목적에 위배됩니다. 나는 그것을 하드 코딩 할 필요가 없으며'namedtuple'처럼 멋진'repr'을 가지고 싶다. – JeromeJ

+0

@JeromeJ 원하는대로 만들 수 있습니다. 클래스의 어떤 것에서 빌드하고 싶다면 역시 그렇게 할 수있다. – Buzz

+0

나는 길다란'def __repr __ (self) : \ return 'className (attrA = {attrA}, attrB = {attrB})'로 시작했다. format (** self))'를 사용합니다. 이는 성가신 것이지 동적이지 않습니다. 괜찮습니다. – JeromeJ

1

내가 당신이라면이 작업을 수행 할 수 있습니다 I __repr__ 메서드 정의로 상위 클래스를 만들고 해당 클래스를 자식 클래스에 상속하여 해당 동작을 적용하게됩니다. 나에게, your solution은 매우 사소한 일을 성취하기 위해 거대한 해킹처럼 보입니다. 여기

class BaseClass: 

    # logic can be used with in `__repr__` itself. 
    # creating separate function to make it more clear 
    def _get_formatted_string(self): 
     return '{class_name}({params})'.format(
      class_name=self.__class__.__name__, 
      params=', '.join('{}={}'.format(k, v) for k, v in vars(self).items())) 

    def __repr__(self): 
     return self._get_formatted_string() 

class child(BaseClass): 

    def __init__(self, a, b): 
     self.a = a 
     self.b = b 

원하는 동작한다 : 아래는 샘플입니다

>>> c = child(1, 2) 
>>> repr(c) 
'child(a=1, b=2)' 
>>> str(c) 
'child(a=1, b=2)'