Search code examples
pythonpython-2.7python-3.xconversion-specifier

Creating new conversion specifier in Python


In python we have conversion specifier like

'{0!s}'.format(10)

which prints

'10'

How can I make my own conversion specifiers like

'{0!d}'.format(4561321)

which print integers in following format

4,561,321

Or converts it into binary like

'{0!b}'.format(2)

which prints

10

What are the classes I need to inherit and which functions I need to modify? If possible please provide a small example.

Thanks!!


Solution

  • What you want to do is impossible, because built-in types cannot be modified and literals always refer to built-in types.

    There is a special method to handle the formatting of values, that is __format__, however it only handles the format string, not the conversion specifier, i.e. you can customize how {0:d} is handled but not how {0!d} is. The only things that work with ! are s and r.

    Note that d and b already exist as format specifiers:

    >>> '{0:b}'.format(2)
    '10'
    

    In any case you could implement your own class that handles formatting:

    class MyInt:
        def __init__(self, value):
            self.value = value
        def __format__(self, fmt):
            if fmt == 'd':
                text = list(str(self.value))
            elif fmt == 'b':
                text = list(bin(self.value)[2:])
            for i in range(len(text)-3, 0, -3):
                text.insert(i, ',')
            return ''.join(text)
    

    Used as:

    >>> '{0:d}'.format(MyInt(5000000))
    5,000,000
    >>> '{0:b}'.format(MyInt(8))
    1,000