클래스 인스턴스가 아닌 클래스 자체에 대한 사용자 지정 문자열 표현을 선택하려면 어떻게 해야 합니까?
이 클래스를 고려합니다.
class foo(object):
pass
기본 문자열 표현은 다음과 같습니다.
>>> str(foo)
"<class '__main__.foo'>"
이 표시를 사용자 지정 문자열로 만들려면 어떻게 해야 합니까?
클래스 인스턴스에 대한 해당 질문은 print()를 사용하여 클래스 인스턴스를 인쇄하는 방법을 참조하십시오.
사실, 이 질문은 Python에서 클래스 자체도 자신의 클래스에 속하는 개체이기 때문에 이 질문의 특별한 경우입니다. 하지만 기본 "클래스의 클래스"가 미리 정의되어 있기 때문에 조언을 어떻게 적용해야 하는지는 직접적으로 명확하지 않습니다.
클래스의 메타 클래스에 구현자입니다.
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object):
__metaclass__ = MC
print(C)
사용하다__str__
수 있는 문자열을 에는 읽을수있문의를경미우는하화열자는,경,__repr__
명확한 표현을 위해.
편집: 파이썬 3 버전
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object, metaclass=MC):
pass
print(C)
class foo(object):
def __str__(self):
return "representation"
def __unicode__(self):
return u"representation"
둘 중 하나를 선택해야 하는 경우__repr__
또는__str__
처럼 첫로 이동합니다.__str__
출들__repr__
그것이 정의되지 않았을 때.
사용자 지정 벡터3 예:
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
이그나시오 바스케스-아브람스의 승인된 답변은 매우 옳습니다.그러나 Python 2세대 제품입니다.현재 파이썬 3의 업데이트는 다음과 같습니다.
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object, metaclass=MC):
pass
print(C)
Python 2와 Python 3 모두에서 실행되는 코드를 원한다면 6개의 모듈에서 다음을 다룹니다.
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!
메타프로그래밍은 일반적으로 매일 필요한 것은 아니지만, 필요할 때는 정말로 필요한 것입니다.
좋은 답변들을 더하면, 장식이 있는 내 버전:
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!
단점:
- 할 수
C
슈퍼 클래스 없이(아니오)class C:
) C
인스턴스는 이상한 파생의 인스턴스가 될 것이므로, 아마도 추가하는 것이 좋을 것입니다.__repr__
경우에도 마찬가지입니다.
또 다른 답변:
- 장식가
- 유형(IDE에서 자동 완성 상태를 유지함)
- v3.10 기준 작업
import typing
class ClassReprMeta(type):
def __repr__(self):
attrs_str = ", ".join(
f"{key}={getattr(self, key)}"
for key in dir(self)
if not key.startswith("_")
)
return f"{self.__name__}({attrs_str})"
T = typing.TypeVar("T")
def printable_class(cls: T) -> T:
"""Decorator to make a class object printable"""
return ClassReprMeta(cls.__name__, cls.__bases__, dict(cls.__dict__))
@printable_class
class CONFIG:
FIRST = 1
SECOND = 2
print(CONFIG) # CONFIG(FIRST=1, SECOND=2)
이 작업을 수행하려면 메타 클래스가 필요하지만 매개 변수를 사용하려면 메타 클래스 자체가 필요하므로 어휘 범위를 통해 이름을 캡처하는 메타 클래스를 사용하여 수행할 수 있습니다.
저는 이것이 몇몇 대안보다 읽기/따라가기가 조금 쉽다고 생각합니다.
class type_: pass
def create_type(name):
# we do this so that we can print the class type out
# otherwise we must instantiate it to get a proper print out
class type_metaclass(type):
def __repr__(self):
return f'<{name}>'
class actual_type(type_, metaclass=type_metaclass):
pass
return actual_type
my_type = create_type('my_type')
print(my_type)
# prints "<my_type>"
언급URL : https://stackoverflow.com/questions/4932438/how-can-i-choose-a-custom-string-representation-for-a-class-itself-not-instance
'programing' 카테고리의 다른 글
R에서 =와 <->의 차이점은 무엇입니까? (0) | 2023.06.28 |
---|---|
:not() 유사 클래스에 여러 개의 인수가 있을 수 있습니까? (0) | 2023.06.28 |
꺼내기 요청에서 커밋을 제거하는 방법 (0) | 2023.06.28 |
Oracle SQL - 쉼표에 대한 소수점 변경 (0) | 2023.06.28 |
SQL Server Management Studio GUI에서 반환한 소스와 동일한 SQL Server 저장 프로시저 소스를 프로그래밍 방식으로 검색하시겠습니까? (0) | 2023.06.28 |