Reputation: 12697
I'd like to change the thousands separator such that {:,}.format(1234)
in Python uses a different character. The separator should be '\u066c'
.
How can I set this without affecting any other locals settings?
EDIT: Any other suggestion for a unimposing separator viable in a fixed with font is welcome!
Upvotes: 7
Views: 1719
Reputation: 1123420
Your options are to either take the ,
formatted output and replace the commas, switch locales and use the 'n'
number format (which will format the number based on the current locale), or use a third party library like babel. The latter gives you full locale control over number formatting, for example, provided there is a locale that uses U+066C as the thousands separator.
With the format()
function, the first option is quite straight-forward really:
>>> format(1234, ',').replace(',', '\u066c')
'1٬234'
I have yet to find a locale that directly would use \u066c
for Western Arabic numerals however; U+066C is commonly used only with Eastern Arabic numerals instead. Babel doesn't include any such locale data, at least.
You can pass any babel Locale
object in to the babel.numbers.format_number()
function, so if you need a custom separator you can clone an existing locale and set the Locale.number_symbols['group']
value:
from copy import deepcopy
from babel import Locale
us_locale = Locale('en', 'US')
base_locale.number_symbols # ensure instance has been populated
altered_locale = deepcopy(us_locale)
altered_locale.number_symbols['group'] = '\u066c'
Note that you have to access an attribute (or the ._data
property) to trigger loading the locale configuration, before copying. Otherwise, the data between the original (source) locale and the altered locale will be shared (so the us_locale
object in my snippet above would have the same number separator.
Using the altered_locale
object now results in the expected output:
>>> from babel.numbers import format_number
>>> format_number(1234, locale=altered_locale)
'1٬234'
Upvotes: 9
Reputation: 19912
Taking Martijn's excellent answer further for use in Django, on how to override a locale in a Django template.
File myapp/templatetags/extra.py
from django import template
from django.utils.translation import get_language
from copy import deepcopy
from babel import Locale
from babel.numbers import format_number
register = template.Library()
@register.filter
def currency(value):
lang = get_language()
locale = deepcopy(Locale(lang))
if lang == 'ru': # for example if russian
locale.number_symbols['group'] = '.'
return format_number(value, locale=locale)
In template:
{% load extra %}
{{ price|currency }}
Upvotes: 3