1

I'd like to create a __str__ method that creates the string in various formats according to user choice.

The best I have come up with is to make a __str__(**kwargs) method, and this seems to work ok, but it isn't compatible with str(obj) or print(obj). In other words I have to use print(obj.__str__(style='pretty')) rather than print(obj, style='pretty').

1
  • Take **kwargs in the constructor rather than the function itself. Commented Mar 6, 2015 at 17:48

1 Answer 1

8

Implement the object.__format__() method instead, and a user can then specify the formatting required with the format() function and str.format() method:

print(format(obj, 'pretty'))

or

print('This object is pretty: {:pretty}'.format(obj))

You probably want to delegate most of the handling of the format on to str.__format__:

def __format__(self, spec):
    if spec.endswith('pretty'):
        prettified = self.pretty_version()
        return prettified.__format__(spec[:-6])
    return str(self).__format__(spec)

That way you can still support all the field width and padding alignment options that the default str.__format__ method supports.

Demo:

>>> class Foo():
...     def __str__(self):
...         return 'plain foo'
...     def pretty_version(self):
...         return 'pretty foo'
...     def __format__(self, spec):
...         if spec.endswith('pretty'):
...             prettified = self.pretty_version()
...             return prettified.__format__(spec[:-6])
...         return str(self).__format__(spec)
... 
>>> f = Foo()
>>> print(f)
plain foo
>>> print(format(f))
plain foo
>>> print(format(f, 'pretty'))
pretty foo
>>> print(format(f, '>20pretty'))
          pretty foo
>>> print('This object is pretty: {:^20pretty}!'.format(f))
This object is pretty:      pretty foo     !
Sign up to request clarification or add additional context in comments.

2 Comments

This works great, but it behaves unexpectedly when my pretty string is multi line. If one line, then >20 tabs the string over like your example... but if multi line, it has no effect. Do you have a possible solution?
@KeithLucas: You'd have to apply the formatting manually to each line then; str.__format__ doesn't support applying field widths to separate lines.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.