Utiliser les services de localisation
Les paramètres linguistiques par défaut
La bibliothèque standard locale
est l'interface de Python avec les routines de localisation basées sur le langage C.
L'usage de base est le suivant :
import locale
locale.atof('123,456')
Dans les pays où les ,
est traité comme un séparateur de milliers, cela renverrait 123456.0
; dans les pays où il est traité comme un point décimal, il renverrait 123.456
.
Cependant, par défaut, cela ne fonctionnera pas :
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/locale.py", line 326, in atof
return func(delocalize(string))
ValueError: could not convert string to float: '123,456'
En effet, par défaut, le programme se trouve "dans une locale" qui a rien à voir avec la plate-forme sur laquelle le code est exécuté, mais est définie par la norme POSIX. Comme l'explique la documentation :
Au départ, lorsqu'un programme est lancé, la locale est la locale C
locale, quelle que soit la locale préférée de l'utilisateur. Il y a une exception : l'option LC_CTYPE
est modifiée au démarrage afin de remplacer le codage des paramètres linguistiques par le codage des paramètres linguistiques préféré de l'utilisateur. Le programme doit explicitement indiquer qu'il veut les paramètres linguistiques préférés de l'utilisateur pour les autres catégories en appelant setlocale(LC_ALL, '')
.
En d'autres termes, hormis la prise en compte du paramètre par défaut du système pour le codage de caractères préféré dans les fichiers texte (de nos jours, il s'agit probablement d'UTF-8), par défaut, l'option locale
interprétera les données de la même manière que Python lui-même (via une locale nommée C
d'après le langage de programmation C). locale.atof
fera la même chose que float
passe une chaîne de caractères, et de la même façon locale.atoi
imitera int
.
Utilisation d'une locale de l'environnement
Faire de la setlocale
mentionné dans la citation ci-dessus de la documentation, récupère les paramètres linguistiques de l'environnement de l'utilisateur. Ainsi :
>>> import locale
>>> # passing an empty string asks for a locale configured on the
>>> # local machine; the return value indicates what that locale is.
>>> locale.setlocale(locale.LC_ALL, '')
'en_CA.UTF-8'
>>> locale.atof('123,456.789')
123456.789
>>> locale.atof('123456.789')
123456.789
La locale ne se préoccupe pas de savoir si les séparateurs de milliers sont au bon endroit - elle les reconnaît et les filtre :
>>> locale.atof('12,34,56.789')
123456.789
Dans les versions 3.6 et ultérieures, il ne s'occupera pas non plus des underscores, qui sont gérés séparément par la fonction intégrée float
y int
conversion :
>>> locale.atof('12_34_56.789')
123456.789
De l'autre côté, la chaîne format
et les chaînes f, sont sensibles à la localisation si la méthode n
est utilisé :
>>> f'{123456.789:.9n}' # `.9` specifies 9 significant figures
'123,456.789'
Sans le précédent setlocale
la sortie ne comporterait pas de virgule.
Définition explicite d'une locale
Il est également possible de définir des paramètres régionaux temporaires, en utilisant le nom régional approprié, et d'appliquer ces paramètres uniquement à un aspect spécifique de la localisation. Pour obtenir une analyse et un formatage localisés uniquement pour les nombres, par exemple, utilisez LC_NUMERIC
plutôt que LC_ALL
dans le setlocale
appel.
Voici quelques exemples :
>>> # in Denmark, periods are thousands separators and commas are decimal points
>>> locale.setlocale(locale.LC_NUMERIC, 'en_DK.UTF-8')
'en_DK.UTF-8'
>>> locale.atof('123,456.789')
123.456789
>>> # Formatting a number according to the Indian lakh/crore system:
>>> locale.setlocale(locale.LC_NUMERIC, 'en_IN.UTF-8')
'en_IN.UTF-8'
>>> f'{123456.789:9.9n}'
'1,23,456.789'
Les chaînes de caractères locales nécessaires peut dépendre de votre système d'exploitation et peut nécessiter des travaux supplémentaires pour permettre à l .
Pour revenir au comportement par défaut de Python, utilisez l'option C
décrite précédemment, donc : locale.setlocale(locale.LC_ALL, 'C')
.
Mises en garde
Le réglage de la locale affecte le comportement du programme de manière globale et n'est pas sans risque pour les threads. S'il est effectué, il doit normalement l'être une seule fois au début du programme. Je cite à nouveau la documentation :
Il est généralement déconseillé d'appeler setlocale()
dans une routine de la bibliothèque, puisqu'elle a un effet secondaire sur l'ensemble du programme. La sauvegarde et la restauration sont presque aussi mauvaises : elles sont coûteuses et affectent les autres threads qui s'exécutent par hasard avant que les paramètres n'aient été restaurés.
Si, lors du codage d'un module destiné à un usage général, vous avez besoin d'une version indépendante de la locale d'une opération qui est affectée par la locale (comme certains formats utilisés avec time.strftime()
), vous devrez trouver un moyen de le faire sans utiliser la routine de la bibliothèque standard. Il est encore mieux de se convaincre que l'utilisation des paramètres régionaux est acceptable. Ce n'est qu'en dernier recours que vous devez documenter le fait que votre module n'est pas compatible avec les langages de programmation non standard. C
les paramètres linguistiques.
Lorsque le code Python est intégré dans un programme C, la définition de la locale peut même affecter le code C :
Les modules d'extension ne doivent jamais appeler setlocale()
sauf pour connaître la langue locale actuelle. Mais comme la valeur de retour ne peut être utilisée que de manière portative pour la restaurer, ce n'est pas très utile (sauf peut-être pour savoir si la locale est ou non C
).
(N.B. : lorsque setlocale
est appelé avec un seul category
ou avec l'argument None
- pas une chaîne vide - pour le nom de la locale, cela ne change rien et renvoie simplement le nom de la locale existante).
Il s'agit donc pas a été conçu comme un outil, dans le code de production, pour tester expérimentalement l'analyse ou le formatage de données destinées à différentes langues. Les exemples ci-dessus ne visent qu'à illustrer le fonctionnement du système. Pour ce faire, recherchez une bibliothèque d'internationalisation tierce.
Toutefois, si les données sont toutes formatées en fonction d'une locale spécifique, le fait de spécifier cette locale à l'avance permettra d'utiliser la fonction locale.atoi
y locale.atof
comme remplaçants immédiats des int
y float
sur une chaîne de caractères.
12 votes
Pour ce faire, il convient d'utiliser la fonction
locale
tout le reste n'est qu'un très vilain piratage qui vous causera des ennuis à l'avenir.1 votes
Le bon
locale
est également un très bon moyen de vous tirer une balle dans le pied si vous prévoyez d'utiliser votre programme sur plusieurs systèmes d'exploitation (comme Windows et des variantes de Linux), qui ont des formats de locales différents ou qui pourraient même nécessiter l'installation d'une locale qui supporte le format que vous avez choisi...