Mastering Objectoriented Python
上QQ阅读APP看书,第一时间看更新

Non collection __str__() and __repr__()

As we saw previously, the output from __str__() and __repr__() are not very informative. We'll almost always need to override them. The following is an approach to override __str__() and __repr__() when there's no collection involved. These methods belong to the Card class, defined previously:

    def __repr__( self ):
        return "{__class__.__name__}(suit={suit!r}, rank={rank!r})".format(
            __class__=self.__class__, **self.__dict__)
    def __str__( self ):
        return "{rank}{suit}".format(**self.__dict__)

These two methods rely on passing the object's internal instance variable dictionary, __dict__, to the format() function. This isn't appropriate for objects that use __slots__; often, these are immutable objects. The use of names in the format specifications makes the formatting more explicit. It also makes the format template longer. In the case of __repr__(), we passed in the internal __dict__ plus the object's __class__ as keyword argument values to the format() function.

The template string uses two kinds of format specifications:

  • The {__class__.__name__} template that could also be written as {__class__.__name__!s} to be more explicit about providing a simple string version of the class name
  • The {suit!r} and {rank!r} template both use the !r format specification to produce the repr() method of the attribute values

In the case of __str__(), we've only passed the object's internal __dict__. The formatting uses implicit {!s} format specifications to produce the str() method of the attribute values.