考虑这个类:

class foo(object):
    pass

默认的字符串表示形式是这样的:

>>> str(foo)
"<class '__main__.foo'>"

如何使此显示自定义字符串?


参见如何使用print()打印类的实例?有关类实例的相应问题。

事实上,这个问题实际上是那个问题的一个特例——因为在Python中,类本身也是属于它们自己类的对象——但如何应用这个建议并不直接明显,因为默认的“类的类”是预定义的。


当前回答

在类的元类中实现__str__()或__repr__()。

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

class C(object):
  __metaclass__ = MC

print(C)

使用__str__如果你指的是可读的字符串,使用__repr__表示明确的表示。

编辑:Python 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"

另一个答案是:

装饰 类型(在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>"

在类的元类中实现__str__()或__repr__()。

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

class C(object):
  __metaclass__ = MC

print(C)

使用__str__如果你指的是可读的字符串,使用__repr__表示明确的表示。

编辑:Python 3版本

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

class C(object, metaclass=MC):
    pass


print(C)

只是在所有的好答案之外,加上我的装饰版本:

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(没有类C:) C实例将是一些奇怪的派生实例,因此为实例添加__repr__可能是一个好主意。