lordzuko
lordzuko

Reputation: 763

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!!

Upvotes: 1

Views: 391

Answers (2)

binu.py
binu.py

Reputation: 1216

Try not to make your own and try to use default functions already present in python. You can use,

'{0:b}'.format(2)  # for binary
'{0:d}'.format(2)  # for integer
'{0:x}'.format(2)  # for hexadecimal
'{0:f}'.format(2)  # for float
'{0:e}'.format(2)  # for exponential

Please refer https://docs.python.org/2/library/string.html#formatspec for more.

Upvotes: 1

Bakuriu
Bakuriu

Reputation: 101919

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

Upvotes: 2

Related Questions