개발/Python

클래스 개체에 대한 사용자 지정 문자열 표현을 만드는 방법은 무엇입니까?

MinorMan 2021. 1. 8. 05:55
반응형

<질문>

이 클래스를 고려하십시오.

class foo(object):
    pass

기본 문자열 표현은 다음과 같습니다.

>>> str(foo)
""

이 디스플레이를 사용자 지정 문자열로 만들려면 어떻게해야합니까?


<답변1>

도구__str__()또는__repr__()클래스의 메타 클래스에서.

class MC(type):
  def __repr__(self):
    return 'Wahaha!'

class C(object):
  __metaclass__ = MC

print C

사용하다__str__읽을 수있는 문자열 화를 의미하는 경우__repr__모호하지 않은 표현을 위해.


<답변2>

class foo(object):
    def __str__(self):
        return "representation"
    def __unicode__(self):
        return u"representation"

<답변3>

다음 중에서 선택해야하는 경우__repr__또는__str__기본 구현으로 첫 번째로 이동__str__전화__repr__정의되지 않았을 때.

Custom Vector3 예제 :

class Vector3(object):
    def __init__(self, args):
        self.x = args[0]
        self.y = args[1]
        self.z = args[2]

    def __repr__(self):
        return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)

    def __str__(self):
        return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)

이 예에서repr직접 사용 / 실행할 수있는 문자열을 다시 반환하는 반면str디버그 출력으로 더 유용합니다.

v = Vector3([1,2,3])
print repr(v)    #Vector3([1,2,3])
print str(v)     #x:1, y:2, z:3

<답변4>

Ignacio Vazquez-Abrams' approved answer아주 맞습니다. 그러나 Python 2 세대입니다. 현재 최신 Python 3에 대한 업데이트는 다음과 같습니다.

class MC(type):
  def __repr__(self):
    return 'Wahaha!'

class C(object, metaclass=MC):
    pass

print(C)

Python 2와 Python 3 모두에서 실행되는 코드를 원하는 경우six모듈에서 다룬 내용 :

from __future__ import print_function
from six import with_metaclass

class MC(type):
  def __repr__(self):
    return 'Wahaha!'

class C(with_metaclass(MC)):
    pass

print(C)

마지막으로, 커스텀 정적 repr을 원하는 클래스가 하나 있다면 위의 클래스 기반 접근 방식이 훌륭하게 작동합니다. 그러나 여러 개가있는 경우 다음과 유사한 메타 클래스를 생성해야합니다.MC각각에 대해 지루할 수 있습니다. 이 경우 메타 프로그래밍을 한 단계 더 발전시키고 메타 클래스 팩토리를 생성하면 상황이 좀 더 깔끔해집니다.

from __future__ import print_function
from six import with_metaclass

def custom_class_repr(name):
    """
    Factory that returns custom metaclass with a class ``__repr__`` that
    returns ``name``.
    """
    return type('whatever', (type,), {'__repr__': lambda self: name})

class C(with_metaclass(custom_class_repr('Wahaha!'))): pass

class D(with_metaclass(custom_class_repr('Booyah!'))): pass

class E(with_metaclass(custom_class_repr('Gotcha!'))): pass

print(C, D, E)

인쇄물:

Wahaha! Booyah! Gotcha!

메타 프로그래밍은 일반적으로 매일 필요한 것이 아닙니다. 그러나 필요할 때 실제로 그 자리를 차지합니다!


<답변5>

모든 훌륭한 답변에 장식이있는 내 버전을 추가하면됩니다.

from __future__ import print_function
import six

def classrep(rep):
    def decorate(cls):
        class RepMetaclass(type):
            def __repr__(self):
                return rep

        class Decorated(six.with_metaclass(RepMetaclass, cls)):
            pass

        return Decorated
    return decorate


@classrep("Wahaha!")
class C(object):
    pass

print(C)

stdout :

Wahaha!

아래쪽 :

  1. 선언 할 수 없습니다.C슈퍼 클래스없이 (아니class C:)
  2. C인스턴스는 이상한 파생의 인스턴스가 될 것입니다. 따라서__repr__인스턴스도 마찬가지입니다.
반응형