如何为一个类定义__str__方法?

38 投票
3 回答
63350 浏览
提问于 2025-04-17 06:23

在Python中,object类是所有(新式)类的根基类。至少在默认情况下,对任何object子类的“类实例”使用strrepr时,得到的结果是一样的:

>>> class spam(object): pass
... 
>>> str(spam)
"<class '__main__.spam'>"
>>> str(spam) == repr(spam)

我想定义一个object的子类,叫做fancyobject,它在各方面都和object相同,唯一的不同是对fancyobject本身使用strrepr时,输出的结果会不同:

>>> class ham(fancyobject): pass
...
>>> str(ham)
'ham'
>>> repr(ham)
"<class '__main__.ham'>"

在Python中,有办法做到这一点吗?

附注:我知道__str__这个特殊方法,但我理解的是,如果类A重写了__str__,那么这个重写的方法只会在对A的实例调用str时被调用,而不是在对A本身调用时。也就是说:

>>> class A(object):
...     def __str__(self):
...         return 'from new __str__: ' + object.__str__(self)
... 
>>> str(A())
'from new __str__: <__main__.A object at 0x7f79c62a5310>'
>>> str(A)
"<class '__main__.A'>"

3 个回答

4

这是关于Python 3的新答案。简单来说,你可以在定义类的时候,把一个元类作为关键字参数传进去。

class fancytype(type):
    def __str__(self):
        return self.__name__
class ham(metaclass=fancytype):
    pass
print(ham)

打印输出

ham
7

你还可以这样为整个模块设置默认的元类

class fancytype(type):
    def __str__(self):
        return self.__name__

__metaclass__ = fancytype

class ham:
    pass
print ham
45

其实,类型的机制和对象实例是一样的。类型本身也是对象,所以它们通过调用自己类型上的 __str__() 方法来转换成字符串,这个类型叫做“ metaclass”(元类)。所以你需要在元类上重写 __str__() 方法:

class fancytype(type):
    def __str__(self):
        return self.__name__
class ham(object):
    __metaclass__ = fancytype
print ham

打印结果是

ham

撰写回答