3

I'm working on a Python project and I'm hoping to use a few shortcuts to help format class data in a string. More specifically, I would like to be able to use something similar to '{a}{b}{c}'.format(**vars(self), [strlen, strlen, strlen]) and specify the string length of each attribute that is displayed. For example:

class Dummy(object):
    def __init__(self):
        self.value1 = 'A VALUE'
        self.value2 = 'ANOTHER VALUE'
        self.value3 = 'THIRD VALUE'

    def to_s(self):
        # want value1 to be 20 chars
        # value2 to be 8 chars
        # value3 to be 10 chars
        # is something similar to this possible
        return '{value1},{value2},{value3}'.format(**vars(self), [20, 8, 10])


    def to_s2(self):
        # or will I have to reference each explicitly and specify the either padding or slicing?
        return '{},{},{}'.format(self.value1.ljust(20), self.value2[:8], self.value3[:10])

I know it's a long shot, but a couple of these classes have 30 or 40 attribs and it would make life so much easier if this is doable.

1
  • 1
    Why not do this in __str__() method, if you want it to be the default string-formatting for that class? Commented Jan 9, 2024 at 21:31

2 Answers 2

3

You can nest {} fields inside {} fields, but only one level of nesting is permitted. Fortunately, only one level of nesting is actually needed. :)

From Format String Syntax:

A format_spec field can also include nested replacement fields within it. These nested replacement fields may contain a field name, conversion flag and format specification, but deeper nesting is not allowed. The replacement fields within the format_spec are substituted before the format_spec string is interpreted. This allows the formatting of a value to be dynamically specified.

class Dummy(object):
    def __init__(self):
        self.value1 = 'A VALUE'
        self.value2 = 'ANOTHER VALUE'
        self.value3 = 'THIRD VALUE'

    def __str__(self):
        # want value1 to be 20 chars
        # value2 to be 8 chars
        # value3 to be 10 chars
        return '{value1:{0}},{value2:{1}},{value3:{2}}'.format(*[20, 8, 10], **vars(self))

print(Dummy())

output

A VALUE             ,ANOTHER VALUE,THIRD VALUE
Sign up to request clarification or add additional context in comments.

1 Comment

Note that this also applies to formatted string literals, aka f-strings.
1

Something like this might work:

class Dummy(object):
    def __init__(self):
        self.value1 = 'A VALUE'
        self.value2 = 'ANOTHER VALUE'
        self.value3 = 'THIRD VALUE'

    def to_s(self):
        return '{0.value1:<20},{0.value2:8},{0.value3:10}'.format(self)

Se more details about formatting in https://docs.python.org/2/library/string.html#formatstrings. In case you want longer list of attributes and more dynamic formatting you can also construct format string dynamically, e.g. (untested):

    field_formats = [('value1', '<20'),
                     ('value2', '8'),
                     ('value3', '>10'))  # etc.

    def to_s(self):
        fmt = ','.join('{0.%s:%s}' % fld for fld in field_formats)
        return fmt.format(self)

Comments

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.