Scopo | Formatta ed elabora valori che dipendono dalla posizione geografica o lingua |
Versione Python | 1.5 e superiore |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per le versioni 3.x di Python
Il modulo locale è parte della libreria per il supporto all'internazionalizzazione e la localizzazione di Python. Fornisce un modo standard per gestire operazioni che potrebbero dipendere dal linguaggio o dalla posizione geografica di un utente. Ad esempio gestisce la formattazione dei numeri come valori di valuta, il confronto di stringhe per ordinamento ed il lavorare con le date. Non si occupa di traduzioni (si veda il modulo gettext ) o di codifica Unicode.
Il metodo più comune per consentire all'utente di modificare le impostazioni di localizzazione per un'applicazione è tramite una variabile di ambiente (
LC_ALL
,
LC_CTYPE
,
LANG
o
LANGUAGE
, a seconda della piattaforma). L'applicazione quindi chiama
setlocale()
senza un valore specifico, e viene usato il valore della variabile d'ambiente.
import locale
import os
import pprint
import codecs
import sys
sys.stdout = codecs.getwriter('UTF-8')(sys.stdout)
# Impostazioni predefinite in base all'ambiente dell'utente.
locale.setlocale(locale.LC_ALL, '')
print 'Impostazioni ambiente:'
for env_name in [ 'LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE' ]:
print '\t%s = %s' % (env_name, os.environ.get(env_name, ''))
# Qual'è la localizzazione?
print
print 'Localizzazione dall\'ambiente:', locale.getlocale()
template = """
Formattazione numerica:
Separatore decimale : "%(decimal_point)s"
Posizioni raggruppamento : %(grouping)s
Separatore migliaia : "%(thousands_sep)s"
Formattazione di valuta:
Simbolo valuta internazionale : "%(int_curr_symbol)r"
Simbolo valuta locale : %(currency_symbol)r (%(currency_symbol_u)s)
Simbolo che precede un valore positivo : %(p_cs_precedes)s
Simbolo che precede un valore negativo : %(n_cs_precedes)s
Separatore decimale : "%(mon_decimal_point)s"
Cifre in valori frazionari : %(frac_digits)s
Cifre in valori frazionari, internazionale: %(int_frac_digits)s
Posizioni raggruppamento : %(mon_grouping)s
Separatore migliaia : "%(mon_thousands_sep)s"
Segno positivo : "%(positive_sign)s"
Posizione segno positivo : %(p_sign_posn)s
Segno negativo : "%(negative_sign)s"
Posizione segno negativo : %(n_sign_posn)s
"""
sign_positions = {
0 : 'Racchiuso tra parentesi',
1 : 'Prima di valore e simbolo',
2 : 'Dopo valore e simbolo',
3 : 'Prima del valore',
4 : 'Dopo il valore',
locale.CHAR_MAX : 'Non specificato',
}
info = {}
info.update(locale.localeconv())
info['p_sign_posn'] = sign_positions[info['p_sign_posn']]
info['n_sign_posn'] = sign_positions[info['n_sign_posn']]
# converte il simbolo di valuta in unicode
info['currency_symbol_u'] = info['currency_symbol'].decode('utf-8')
print (template % info)
Il metodo
localeconv
ritorna un dizionario contenente le convenzioni di localizzazione. La lista completa dei nomi dei nomi di valori e definizioni viene trattato nella documentazione della libreria standard.
Un PC sul quale gira un sistema operativo Linux, kernel 4.2.0-16-generic, con le variabili non impostate fornisce i seguenti risultati:
$ export LC_ALL=; export LANG=; export LC_CTYPE=; export LANGUAGE=; export LC_MONETARY; export LC_MEAUSREMENT=; export LC_TIME; export LC_NAME; export LC_NUMERIC=; export LC_MONETARY=; export LC_TIME=; export LC_NAME=; python locale_env_example.py Impostazioni ambiente: LC_ALL = LC_CTYPE = LANG = LANGUAGE = Localizzazione dall'ambiente: (None, None) Formattazione numerica: Separatore decimale : "." Posizioni raggruppamento : [] Separatore migliaia : "" Formattazione di valuta: Simbolo valuta internazionale : "''" Simbolo valuta locale : '' () Simbolo che precede un valore positivo : 127 Simbolo che precede un valore negativo : 127 Separatore decimale : "" Cifre in valori frazionari : 127 Cifre in valori frazionari, internazionale: 127 Posizioni raggruppamento : [] Separatore migliaia : "" Segno positivo : "" Posizione segno positivo : Non specificato Segno negativo : "" Posizione segno negativo : Non specificato
Eseguendo lo stesso script con la variabile
LANG
impostata mostra come la localizzazione e la codifica predefinita cambiano:
France(
fr_FR
)
$ LANG=fr_FR LC_CTYPE=fr_FR LC_ALL=fr_FR python locale_env_example.py Impostazioni ambiente: LC_ALL = fr_FR LC_CTYPE = fr_FR LANG = fr_FR LANGUAGE = Locale dall'ambiente: ('fr_FR', 'ISO8859-1') Formattazione numerica: Separatore decimale : "," Posizioni raggruppamento : [127] Separatore migliaia : "" Formattazione di valuta: Simbolo valuta internazionale : "'EUR '" Simbolo valuta locale : 'Eu' (Eu) Simbolo che precede un valore positivo : 0 Simbolo che precede un valore negativo : 0 Separatore decimale : "," Cifre in valori frazionari : 2 Cifre in valori frazionari, internazionale: 2 Posizioni raggruppamento : [3, 3, 0] Separatore migliaia : " " Segno positivo : "" Posizione segno positivo : Prima di valore e simbolo Segno negativo : "-" Posizione segno negativo : Prima di valore e simbolo
Spagna: (
es_ES
):
$ LANG=es_ES LC_CTYPE=es_ES LC_ALL=es_ES python locale_env_example.py Impostazioni ambiente: LC_ALL = es_ES LC_CTYPE = es_ES LANG = es_ES LANGUAGE = Locale dall'ambiente: ('es_ES', 'ISO8859-1') Formattazione numerica: Separatore decimale : "," Posizioni raggruppamento : [127] Separatore migliaia : "" Formattazione di valuta: Simbolo valuta internazionale : "'EUR '" Simbolo valuta locale : 'Eu' (Eu) Simbolo che precede un valore positivo : 1 Simbolo che precede un valore negativo : 1 Separatore decimale : "," Cifre in valori frazionari : 2 Cifre in valori frazionari, internazionale: 2 Posizioni raggruppamento : [3, 3, 0] Separatore migliaia : "." Segno positivo : "" Posizione segno positivo : Prima di valore e simbolo Segno negativo : "-" Posizione segno negativo : Prima di valore e simbolo
Portogallo (
pt_PT
):
$ LANG=pt_PT LC_CTYPE=pt_PT LC_ALL=pt_PT python locale_env_example.py Impostazioni ambiente: LC_ALL = pt_PT LC_CTYPE = pt_PT LANG = pt_PT LANGUAGE = Locale dall'ambiente: ('pt_PT', 'ISO8859-1') Formattazione numerica: Separatore decimale : "," Posizioni raggruppamento : [] Separatore migliaia : " " Formattazione di valuta: Simbolo valuta internazionale : "'EUR '" Simbolo valuta locale : 'Eu' (Eu) Simbolo che precede un valore positivo : 0 Simbolo che precede un valore negativo : 0 Separatore decimale : "." Cifre in valori frazionari : 2 Cifre in valori frazionari, internazionale: 2 Posizioni raggruppamento : [3, 3, 0] Separatore migliaia : "." Segno positivo : "" Posizione segno positivo : Prima di valore e simbolo Segno negativo : "-" Posizione segno negativo : Prima di valore e simbolo
Polonia (
pl_PL
):
$ LANG=pl_PL LC_CTYPE=pl_PL LC_ALL=pl_PL python locale_env_example.py Impostazioni ambiente: LC_ALL = pl_PL LC_CTYPE = pl_PL LANG = pl_PL LANGUAGE = Locale dall'ambiente: ('pl_PL', 'ISO8859-2') Formattazione numerica: Separatore decimale : "," Posizioni raggruppamento : [3 , 3, 0] Separatore migliaia : " " Formattazione di valuta: Simbolo valuta internazionale : "'PLN '" Simbolo valuta locale : 'z\xc5\x82' (zł) Simbolo che precede un valore positivo : 1 Simbolo che precede un valore negativo : 1 Separatore decimale : "," Cifre in valori frazionari : 2 Cifre in valori frazionari, internazionale: 2 Posizioni raggruppamento : [3, 3, 0] Separatore migliaia : " " Segno positivo : "" Posizione segno positivo : Dopo valore Segno negativo : "-" Posizione segno negativo : Dopo valore
Il risultato dell'esempio qui sotto mostra che modificando la localizzazione viene aggiornata l'impostazione del simbolo della moneta ed il carattere di separazione tra numeri interi e frazioni decimali. Questo esempio itera attraverso diverse localizzazioni per stampare un valore di moneta positivo e negativo formattato per ogni localizzazione:
import locale
sample_locales = [ ('USA', 'en_US'),
('Francia', 'fr_FR'),
('Spagna', 'es_ES'),
('Portogallo', 'pt_PT'),
('Polonia' , 'pl_PL'),
]
for name, loc in sample_locales:
locale.setlocale(locale.LC_ALL, loc)
print '%20s: %10s %10s' % (name, locale.currency(1234.56), locale.currency(-1234.56))
Il risultato è questa piccola tabella:
$ python locale_currency_example.py USA: $1234.56 -$1234.56 Francia: 1234,56 Eu 1234,56 Eu- Spagna: Eu 1234,56 -Eu 1234,56 Portogallo: 1234.56 Eu -1234.56 Eu Polonia: zł 1234,56 zł 1234,56-
Anche i numeri, non relazionati alla moneta, sono formattati diversamente a seconda della localizzazione. In particolare il carattere di raggruppamento ( grouping ) usato per separare grandi numeri in parti più leggibili viene cambiato:
import locale
sample_locales = [ ('USA', 'en_US'),
('Francia', 'fr_FR'),
('Spagna', 'es_ES'),
('Portogallo', 'pt_PT'),
('Polonia' , 'pl_PL'),
]
print '%20s %15s %20s' % ('Localizzazione', 'Interi', 'Virgola variabile')
for name, loc in sample_locales:
locale.setlocale(locale.LC_ALL, loc)
print '%20s' % name,
print locale.format('%15d', 123456, grouping=True),
print locale.format('%20.2f', 123456.78, grouping=True)
Per formattare numeri senza il simbolo di moneta, usare
format()
invece che
currency()
$ python locale_grouping.py Localizzazione Interi Virgola variabile USA 123,456 123,456.78 France 123456 123456,78 Spain 123456 123456,78 Portugal 123456 123456,78 Poland 123 456 123 456,78
A parte la generazione di un output in diversi formati, il modulo
locale
viene in aiuto in caso di elaborazione dell'input. Esso comprende le funzioni
atoi()
ed
atof()
per convertire stringhe in valori interi ed a virgola mobile in base alle convenzioni di formattazione numerica della localizzazione.
import locale
sample_data = [ ('USA', 'en_US', '1,234.56'),
('Francia', 'fr_FR', '1234,56'),
('Spagna', 'es_ES', '1234,56'),
('Portogallo', 'pt_PT', '1234.56'),
('Polonia', 'pl_PL', '1 234,56'),
]
for name, loc, a in sample_data:
locale.setlocale(locale.LC_ALL, loc)
f = locale.atof(a)
print '%20s: %9s => %f' % (name, a, f)
I valori di raggruppamento e di separazione decimale
$ python locale_atof_example.py USA: 1,234.56 => 1234.560000 Francia: 1234,56 => 1234.560000 Spagna: 1234,56 => 1234.560000 Portogallo: 1234.56 => 1234.560000 Polonia: 1 234,56 => 1234.560000
Un altro importante aspetto della localizzaizone è la formattazione di data ed orario:
import locale
import time
sample_locales = [ ('USA', 'en_US'),
('Francia', 'fr_FR'),
('Spagna', 'es_ES'),
('Portogallo', 'pt_PT'),
('Polonia', 'pl_PL'),
]
for name, loc in sample_locales:
locale.setlocale(locale.LC_ALL, loc)
print '%20s: %s' % (name, time.strftime(locale.nl_langinfo(locale.D_T_FMT)))
$ python locale_date_example.py USA: Thu Feb 21 06:35:54 2013 Francia: Jeu 21 fév 06:35:54 2013 Spagna: jue 21 feb 06:35:54 2013 Portogallo: Qui 21 Fev 06:35:54 2013 Polonia: czw 21 lut 06:35:54 2013
Questa discussione copre solamente alcune delle funzioni di alto livello nel modulo
locale
. Ve ne sono altre di livello più basso (
format_string()
) oppure relative alla gestione della localizzazione per la propria applicazione (
resetlocale()
).