El módulo locale
Cuando se instala un sistema operativo una de las primeras opciones de configuración que se decide es la localización geográfica del equipo o dispositivo. Normalmente, el idioma del sistema operativo se corresponderá con el país seleccionado y dicha elección será también empleada para fijar una serie de convenciones que definen para ese lugar el modo de expresar los números, las cantidades monetarias, los números positivos y negativos, las fechas y horas, etc.
Estas convenciones establecen, entre otros, el carácter que se utiliza en los números para separar la parte entera de la decimal (",", ".", etc.); el carácter que se usa como separador de millares (".", ",", etc.), el símbolo monetario (€, £, $, ¥, etc.), el formato de las fechas y horas, etc.
Afortunadamente, estas definiciones pueden ser utilizadas (y cambiadas) por una aplicación para adaptar la forma en que presentan sus datos a cada territorio. Particularmente, en Python ese es el cometido principal que tiene el módulo locale, incluido en la librería estándar como parte del soporte que ofrece el lenguaje a la internacionalización de las aplicaciones.
Hoy, los distintos sistemas operativos proporcionan herramientas gráficas que permiten modificar de forma fácil las opciones comentadas. En Windows se utiliza la herramienta de "Configuración Regional y de Idioma" y en GNU/Linux ésta, a veces, se denomina de igual forma (como en Ubuntu GNOME) o puede estar integrada en otra herramienta como la de "Soporte de Idiomas" (como sucede en Xubuntu).
Según sea el caso, en Windows las definiciones vigentes del entorno de un usuario son almacenadas en el Registro de Windows (en la rama "HKEY_CURRENT_USER\Control Panel\International") y en un sistema GNU/Linux en los archivos donde se declaran las variables de entorno (LC_ALL, LC_CTYPE, LANG, LANGUAGE) que son ejecutados al iniciar un equipo. Cada plataforma tiene sus propios mecanismos.
En GNU/Linux para consultar desde la línea de comandos las variables de entorno utilizar los comandos env o printenv. En Windows, el comando systeminfo muestra información básica de la configuración regional.
Estas convenciones establecen, entre otros, el carácter que se utiliza en los números para separar la parte entera de la decimal (",", ".", etc.); el carácter que se usa como separador de millares (".", ",", etc.), el símbolo monetario (€, £, $, ¥, etc.), el formato de las fechas y horas, etc.
Afortunadamente, estas definiciones pueden ser utilizadas (y cambiadas) por una aplicación para adaptar la forma en que presentan sus datos a cada territorio. Particularmente, en Python ese es el cometido principal que tiene el módulo locale, incluido en la librería estándar como parte del soporte que ofrece el lenguaje a la internacionalización de las aplicaciones.
Herramienta de Configuración Regional y de Idioma |
Hoy, los distintos sistemas operativos proporcionan herramientas gráficas que permiten modificar de forma fácil las opciones comentadas. En Windows se utiliza la herramienta de "Configuración Regional y de Idioma" y en GNU/Linux ésta, a veces, se denomina de igual forma (como en Ubuntu GNOME) o puede estar integrada en otra herramienta como la de "Soporte de Idiomas" (como sucede en Xubuntu).
Configuración Regional en Registro de Windows |
Según sea el caso, en Windows las definiciones vigentes del entorno de un usuario son almacenadas en el Registro de Windows (en la rama "HKEY_CURRENT_USER\Control Panel\International") y en un sistema GNU/Linux en los archivos donde se declaran las variables de entorno (LC_ALL, LC_CTYPE, LANG, LANGUAGE) que son ejecutados al iniciar un equipo. Cada plataforma tiene sus propios mecanismos.
En GNU/Linux para consultar desde la línea de comandos las variables de entorno utilizar los comandos env o printenv. En Windows, el comando systeminfo muestra información básica de la configuración regional.
Obtener/establecer la configuración regional: setlocate()
La función setlocate() devuelve o establece la configuración regional del entorno de un usuario. El argumento category representa una categoría determinada de configuración (una categoría agrupa un conjunto de definiciones de configuración). Y locale es una cadena que representa el idioma de una localización geográfica determinada:
locale.setlocale(category, locale=None)
Las definiciones de configuración se agrupan en las siguientes categorías:
Ver valores del argumento locale en Windows
En GNU/Linux Ubuntu se pueden consultar los idiomas disponibles con el comando locale -a.
También, se pueden instalar más idiomas con el comando sudo apt-get install language-pack-XXX. Por ejemplo, para instalar la especificación de Japón: sudo apt-get install language-pack-ja. (Es equivalente a utilizar la herramienta de "Soporte de Idiomas").
A continuación, varios ejemplos para fijar la configuración regional en todas las categorías (locale.LC_ALL). Si la cadena del idioma es incorrecta o el idioma no está disponible se producirá la siguiente excepción:
Cuando se desarrolla una aplicación para que funcione en cualquier país teniendo en cuenta la configuración regional, después de importar el módulo locale se establecerá la configuración que tenga el entorno de trabajo del propio usuario. Para ello, el argumento locale de setlocate() debe ser una cadena vacía: ''
Así, si un usuario en España imprime importes utilizando la configuración regional, el símbolo monetario mostrado será el símbolo del euro '€'; si es un londinense, el símbolo de la libra '£'; un japonés, el símbolo del Yen '¥', etc.
locale.setlocale(category, locale=None)
Las definiciones de configuración se agrupan en las siguientes categorías:
- locale.LC_ALL: combinación de todas las categorias.
- locale.LC_NUMERIC: formatos de números.
- locale.LC_TIME: formatos de fechas/horas.
- locale.LC_MONETARY: formatos de valores monetarios.
- locale.LC_COLLATE: para ordenación de cadenas.
- locale.LC_CTYPE: para funciones de tipo de carácter.
- locale.LC_MESSAGES: para visualización de mensajes. (Python no admite mensajes específicos)
Ver valores del argumento locale en Windows
En GNU/Linux Ubuntu se pueden consultar los idiomas disponibles con el comando locale -a.
También, se pueden instalar más idiomas con el comando sudo apt-get install language-pack-XXX. Por ejemplo, para instalar la especificación de Japón: sudo apt-get install language-pack-ja. (Es equivalente a utilizar la herramienta de "Soporte de Idiomas").
A continuación, varios ejemplos para fijar la configuración regional en todas las categorías (locale.LC_ALL). Si la cadena del idioma es incorrecta o el idioma no está disponible se producirá la siguiente excepción:
Error: unsupported locale setting.
Cuando se desarrolla una aplicación para que funcione en cualquier país teniendo en cuenta la configuración regional, después de importar el módulo locale se establecerá la configuración que tenga el entorno de trabajo del propio usuario. Para ello, el argumento locale de setlocate() debe ser una cadena vacía: ''
Así, si un usuario en España imprime importes utilizando la configuración regional, el símbolo monetario mostrado será el símbolo del euro '€'; si es un londinense, el símbolo de la libra '£'; un japonés, el símbolo del Yen '¥', etc.
import locale # Establecer la configuración que tenga el entorno del usuario locale.setlocale(locale.LC_ALL, '') # Establecer configuraciones de países concretos: # Establecer configuración para España en un sistema Windows locale.setlocale(locale.LC_ALL, 'esp') # Establecer configuración para España en Ubuntu locale.setlocale(locale.LC_ALL, 'es_ES.utf8') # Establecer configuración para España en otros sistemas GNU/Linux locale.setlocale(locale.LC_ALL, 'es_ES') # Establecer configuración para Japón en Ubuntu locale.setlocale(locale.LC_ALL, 'ja_JP.utf8') # Establecer configuración para Japón en otros sistemas GNU/Linux locale.setlocale(locale.LC_ALL, 'ja_JP')
Obtener diccionario con configuración actual: locale.localeconv()
La función localeconv() devuelve un diccionario con todas las definiciones de la configuración regional actual.
import locale import pprint # Establecer la configuración del entorno de usuario # En este ejemplo se corresponde con 'es_ES.utf8' (España) locale.setlocale(locale.LC_ALL, '') # Obtener definiciones de la configuración actual configuracion = locale.localeconv() # Imprimir definiciones con pprint para una # lectura agradable: imprimir = pprint.PrettyPrinter() imprimir.pprint(configuracion) ''' Salida para España: {'currency_symbol': '€', 'decimal_point': ',', 'frac_digits': 2, 'grouping': [3, 3, 0], 'int_curr_symbol': 'EUR ', 'int_frac_digits': 2, 'mon_decimal_point': ',', 'mon_grouping': [3, 3, 0], 'mon_thousands_sep': '.', 'n_cs_precedes': 0, 'n_sep_by_space': 1, 'n_sign_posn': 1, 'negative_sign': '-', 'p_cs_precedes': 0, 'p_sep_by_space': 1, 'p_sign_posn': 1, 'positive_sign': '', 'thousands_sep': '.'} ''' # Establecer configuración para Japón # en Ubuntu. locale.setlocale(locale.LC_ALL, 'ja_JP.utf8') # (En Windows utilizar la cadena 'jpn') # Obtener definiciones de Japón configuracion = locale.localeconv() # Imprimir definiciones con pprint para una # lectura agradable imprimir.pprint(configuracion) ''' Salida para Japón: {'currency_symbol': '¥', 'decimal_point': '.', 'frac_digits': 0, 'grouping': [3, 0], 'int_curr_symbol': 'JPY ', 'int_frac_digits': 0, 'mon_decimal_point': '.', 'mon_grouping': [3, 0], 'mon_thousands_sep': ',', 'n_cs_precedes': 1, 'n_sep_by_space': 0, 'n_sign_posn': 4, 'negative_sign': '-', 'p_cs_precedes': 1, 'p_sep_by_space': 0, 'p_sign_posn': 4, 'positive_sign': '', 'thousands_sep': ','} '''
Funciones para aplicar las definiciones de configuración
Para aplicar las definiciones de una configuración regional utilizar las siguientes funciones:
import locale locale.setlocale(locale.LC_ALL, '') # Formatear números de acuerdo con la configuración # actual de LC_NUMERIC valor = 123456.78 locale.format('%10.2f', valor, grouping=True) # '123.456,78' locale.format('%10.2f', valor, grouping=False) # ' 123456,78' # Formatear procesando especificadores de formato % locale.format_string('%i', valor, grouping=True) # '123.456' locale.format_string('%.1f', valor, grouping=True) # '123.456,8' # Formatear números de acuerdo con la # configuración LC_MONETARY actual. locale.currency(valor, symbol=True, grouping=False) # '123456,78 €' # Establecer configuración para Reino Unido locale.setlocale(locale.LC_ALL, 'en_IN') locale.currency(valor, symbol=True, grouping=False) # '₹ 123456.78' # Establecer configuración predeterminada locale.setlocale(locale.LC_ALL, '') # Formatear flotantes como str pero con el carácter # predeterminado para el punto decimal locale.str(valor) # '123456,78' # Comparar dos cadenas de acuerdo con la # configuración LC_COLLATE actual locale.strcoll('Guadalquivir', 'Guadalhorce') # 10 locale.strcoll('Guadalquivir', 'Guadalupe') # -4 locale.strcoll('Guadalupe', 'Guadalupe') # 0 # Definir clave de ordenación de acuerdo a la # configuración actual cadenas = ['Guadalquivir', 'Guadalhorce', 'Guadalupe'] cadenas.sort(key=locale.strxfrm) print(cadenas) # ['Guadalhorce', 'Guadalquivir', 'Guadalupe'] # Convertir cadena en cadena numérica normaliza # de acuerdo con LC_NUMERIC. # Disponible a partir de Python 3.5 cadena = '6543,21' locale.delocalize(cadena) # '6543.21'
Obtener información específica de configuración: locale.nl_langinfo()
La función nl_langinfo() retorna una cadena con información específica de la configuración regional actual. Esta función no está disponible en todos los sistemas y el conjunto de opciones posibles también puede variar entre plataformas.
import locale from datetime import datetime # Establecer configuración del entorno de usuario # En este ejemplo se corresponde con 'es_ES.utf8' (España) locale.setlocale(locale.LC_ALL, '') # Obtener codificación de los caracteres utilizada codificacion = locale.nl_langinfo(locale.CODESET) # 'UTF-8' # En este caso la codificación se utiliza para # convertir una cadena de tipo Unicode a Byte pais = bytes("España", codificacion) print(pais) # b'Espa\xc3\xb1a' # El formato Byte acepta sólo caracteres ASCII y # facilita la creación de archivos de texto. # Obtener formato de fecha y hora formato1 = locale.nl_langinfo(locale.D_T_FMT) # '%a %d %b %Y %T %Z' # Obtener fecha y hora actual e imprimir utilizando # el formato de fecha-hora de la configuración actual hoy = datetime.today() print(hoy.strftime(formato1)) # mié 26 abr 2017 17:24:42 # Obtener formato de fecha e imprimir utilizando # el formato de fecha de la configuración actual formato2 = locale.nl_langinfo(locale.D_FMT) # '%d/%m/%y' print(hoy.strftime(formato2)) # 26/04/17 # Obtener formato de hora e imprimir utilizando # el formato de hora de la configuración actual formato3 = locale.nl_langinfo(locale.T_FMT) # '%T' print(hoy.strftime(formato3)) # 17:24:42 # Obtener cadena para representar la hora con # el formato AM/PM. # Si devuelve cadena vacía se expresa con 24 horas formato4 = locale.nl_langinfo(locale.T_FMT_AMPM) # '' # Obtener nombre completo y abreviado de los días de # la semana en el idioma de la configuración actual for dia in range(1, 8): nombre_dia = 'locale.DAY_' + str(dia) abrev_dia = 'locale.ABDAY_' + str(dia) print(nombre_dia, ':', locale.nl_langinfo(eval(nombre_dia)), '-', locale.nl_langinfo(eval(abrev_dia))) ''' Salida: locale.DAY_1 : domingo - dom locale.DAY_2 : lunes - lun locale.DAY_3 : martes - mar locale.DAY_4 : miércoles - mié locale.DAY_5 : jueves - jue locale.DAY_6 : viernes - vie locale.DAY_7 : sábado - sáb ''' # Obtener nombre completo y abreviado de los meses # en el idioma de la configuración actual for mes in range(1, 13): nombre_mes = 'locale.MON_' + str(mes) abrev_mes = 'locale.ABMON_' + str(mes) print(nombre_mes, ':', locale.nl_langinfo(eval(nombre_mes)), '-', locale.nl_langinfo(eval(abrev_mes))) ''' Salida: locale.MON_1 : enero - ene locale.MON_2 : febrero - feb locale.MON_3 : marzo - mar locale.MON_4 : abril - abr locale.MON_5 : mayo - may locale.MON_6 : junio - jun locale.MON_7 : julio - jul locale.MON_8 : agosto - ago locale.MON_9 : septiembre - sep locale.MON_10 : octubre - oct locale.MON_11 : noviembre - nov locale.MON_12 : diciembre - dic ''' # Obtener carácter que se emplea en los números # para separar la parte entera de la decimal de # la configuración actual locale.nl_langinfo(locale.RADIXCHAR) # ',' # Obtener carácter separador de millares locale.nl_langinfo(locale.THOUSEP) # '.' # Obtener expresión regular que se puede usar con la función regex # para reconocer una respuesta positiva o negativa a una pregunta. locale.nl_langinfo(locale.YESEXPR) # '^[sSyY].*' locale.nl_langinfo(locale.NOEXPR) # '^[nN].*' # Obtener símbolo monetario # El signo '-' indica que el símbolo aparecerá delante del valor # El signo '+' indica que el símbolo aparecerá detrás del valor # El '.' indica que el símbolo aparecerá en la posición del # punto o coma decimal locale.nl_langinfo(locale.CRNCYSTR) # '+€'
Funciones para obtener el idioma y la codificación
Las funciones siguientes permiten obtener el idioma y la codificación de las cadenas de texto de distintos modos:
import locale locale.setlocale(locale.LC_ALL, '') # Determinar configuración a partir de variable de entorno locale.getdefaultlocale() # ('es_ES', 'UTF-8') locale.getdefaultlocale(['LANG']) # ('es_ES', 'UTF-8') # Obtener configuración del entorno local a partir de categoria locale.getlocale() # ('es_ES', 'UTF-8') locale.getlocale(locale.LC_NUMERIC) # ('es_ES', 'UTF-8') # Obtener codificación que se utiliza para representar # las cadenas de texto locale.getpreferredencoding() # 'UTF-8' # Obtener código de configuración regional normalizado locale.normalize('es_ES') # 'es_ES.ISO8859-1' # Establecer configuración regional para la categoria indicada locale.resetlocale(locale.LC_NUMERIC)
Ir al índice del tutorial de Python