89 votes

Python - Obtenez une liste de tous les encodages que python peut encoder

Je suis en train d'écrire un script qui va essayer de codage des octets dans beaucoup de différents encodages dans la version 2.6 de Python. Est-il un moyen pour obtenir une liste des encodages que je peux parcourir?

La raison pour laquelle je suis en train de le faire c'est parce qu'un utilisateur a du texte qui n'est pas codé correctement. Il y a de drôles de personnages. Je sais que le caractère unicode qui est tout gâcher. Je veux être en mesure de donner une réponse comme "Votre éditeur de texte est l'interprétation de cette chaîne comme X d'encodage, de ne pas Y encodage". J'ai pensé que je voudrais essayer de coder le personnage à l'aide d'un codage, puis décode à nouveau en utilisant un autre codage, et de voir si nous obtenons la même séquence de caractères.

c'est à dire quelque chose comme ceci:

for encoding1, encoding2 in itertools.permutation(encodinglist(), 2):
  try:
    unicode_string = my_unicode_character.encode(encoding1).decode(encoding2)
  except:
    pass

101voto

Mark Amery Points 4705

D'autres réponses ici semblent indiquer que la construction de cette liste par programmation est difficile et semé d'embûches. Cependant, cela est probablement inutile étant donné que la documentation contient une liste complète des encodages standard Python supporte. Ici, il est:

["ascii",
 "big5",
 "big5hkscs",
 "cp037",
 "cp424",
 "cp437",
 "cp500",
 "cp720",
 "cp737",
 "cp775",
 "cp850",
 "cp852",
 "cp855",
 "cp856",
 "cp857",
 "cp858",
 "cp860",
 "cp861",
 "cp862",
 "cp863",
 "cp864",
 "cp865",
 "cp866",
 "cp869",
 "cp874",
 "cp875",
 "cp932",
 "cp949",
 "cp950",
 "cp1006",
 "cp1026",
 "cp1140",
 "cp1250",
 "cp1251",
 "cp1252",
 "cp1253",
 "cp1254",
 "cp1255",
 "cp1256",
 "cp1257",
 "cp1258",
 "euc_jp",
 "euc_jis_2004",
 "euc_jisx0213",
 "euc_kr",
 "gb2312",
 "gbk",
 "gb18030",
 "hz",
 "iso2022_jp",
 "iso2022_jp_1",
 "iso2022_jp_2",
 "iso2022_jp_2004",
 "iso2022_jp_3",
 "iso2022_jp_ext",
 "iso2022_kr",
 "latin_1",
 "iso8859_2",
 "iso8859_3",
 "iso8859_4",
 "iso8859_5",
 "iso8859_6",
 "iso8859_7",
 "iso8859_8",
 "iso8859_9",
 "iso8859_10",
 "iso8859_13",
 "iso8859_14",
 "iso8859_15",
 "iso8859_16",
 "johab",
 "koi8_r",
 "koi8_u",
 "mac_cyrillic",
 "mac_greek",
 "mac_iceland",
 "mac_latin2",
 "mac_roman",
 "mac_turkish",
 "ptcp154",
 "shift_jis",
 "shift_jis_2004",
 "shift_jisx0213",
 "utf_32",
 "utf_32_be",
 "utf_32_le",
 "utf_16",
 "utf_16_be",
 "utf_16_le",
 "utf_7",
 "utf_8",
 "utf_8_sig"]

Dans le cas où ils sont pertinents pour tous les cas, les documents également la liste suivante Python-codages spécifiques, dont beaucoup semblent être principalement pour l'usage de Python-même ou qui sont bizarres en quelque sorte, comme l' 'undefined' d'encodage qui jette toujours une exception si vous essayez de l'utiliser. Vous voulez probablement ignorer complètement ces si, à l'instar de la question-asker ici, vous êtes à essayer de comprendre ce que le codage a été utilisé pour du texte que vous venez de rencontrer dans le monde réel.

["idna",
 "mbcs",
 "palmos",
 "punycode",
 "raw_unicode_escape",
 "rot_13",
 "undefined",
 "unicode_escape",
 "unicode_internal",
 "base64_codec",
 "bz2_codec",
 "hex_codec",
 "quopri_codec",
 "string_escape",
 "uu_codec",
 "zlib_codec"]

40voto

John Machin Points 39706

Malheureusement, encodings.aliases.aliases.keys() n'est PAS une réponse appropriée.

aliases(que l'on pourrait/devrait attendre) contient plusieurs cas où les différentes touches sont mappés à la même valeur, par exemple 1252 et windows_1252 sont à la fois mappé cp1252. Vous pourriez gagner du temps si, au lieu de aliases.keys() vous utilisez set(aliases.values()).

MAIS IL y a UN PROBLÈME plus grave: aliases ne contient pas de codecs qui n'ont pas d'alias (comme cp856, cp874, cp875, cp737, et koi8_u).

>>> from encodings.aliases import aliases
>>> def find(q):
...     return [(k,v) for k, v in aliases.items() if q in k or q in v]
...
>>> find('1252') # multiple aliases
[('1252', 'cp1252'), ('windows_1252', 'cp1252')]
>>> find('856') # no codepage 856 in aliases
[]
>>> find('koi8') # no koi8_u in aliases
[('cskoi8r', 'koi8_r')]
>>> 'x'.decode('cp856') # but cp856 is a valid codec
u'x'
>>> 'x'.decode('koi8_u') # but koi8_u is a valid codec
u'x'
>>>

Il est également intéressant de noter que cependant vous obtenir une liste complète des codecs, il peut être une bonne idée d'ignorer les codecs qui ne sont pas sur le codage/décodage des jeux de caractères, mais faire quelque chose d'autre de transformation par exemple, zlib, quopri, et base64.

Ce qui nous amène à la question de savoir POURQUOI vous voulez "essayer de codage des octets dans beaucoup de différents encodages". Si nous savons que nous pouvons être en mesure de vous orienter dans la bonne direction.

Pour un début, c'est ambigu. On Décode les octets en unicode, et un Code unicode en octets. Qui voulez-vous faire?

De quoi êtes-vous vraiment essayer de l'atteindre: Êtes-vous essayer de déterminer le codec à utiliser pour décoder certains les octets reçus, et le plan de l'essayer avec tous les possible de codecs? [note: latin1 décode rien] Êtes-vous en essayant de déterminer la langue de certains de texte unicode en essayant de coder avec tous les possible de codecs? [note: utf8 encoder quelque chose].

23voto

Matt Nordhoff Points 161

Peut-être devriez-vous essayer d'utiliser la bibliothèque Universal Encoding Detector (chardet) au lieu de l'implémenter vous-même.

 >>> import chardet
>>> s = '\xe2\x98\x83' # ☃
>>> chardet.detect(s)
{'confidence': 0.505, 'encoding': 'utf-8'}
 

18voto

u0b34a0f6ae Points 14874

Vous pouvez utiliser une technique pour répertorier tous les modules du package encodings .

 import pkgutil
import encodings

false_positives = set(["aliases"])

found = set(name for imp, name, ispkg in pkgutil.iter_modules(encodings.__path__) if not ispkg)
found.difference_update(false_positives)
print found
 

5voto

Anurag Uniyal Points 31931

Je doute qu'il existe une telle méthode / fonctionnalité dans le module de codecs, mais si vous voyez encoding/__init__.py , la fonction de recherche effectue une recherche dans le dossier des modules d'encodage, afin que vous puissiez faire de même, par exemple.

 >>> os.listdir(os.path.dirname(encodings.__file__))
['cp500.pyc', 'utf_16_le.py', 'gb18030.py', 'mbcs.pyc', 'undefined.pyc', 'idna.pyc', 'punycode.pyc', 'cp850.py', 'big5hkscs.pyc', 'mac_arabic.py', '__init__.pyc', 'string_escape.py', 'hz.py', 'cp037.py', 'cp737.py', 'iso8859_5.pyc', 'iso8859_13.pyc', 'cp861.pyc', 'cp862.py', 'iso8859_9.pyc', 'cp949.py', 'base64_codec.pyc', 'koi8_r.py', 'iso8859_2.py', 'ptcp154.pyc', 'uu_codec.pyc', 'mac_croatian.pyc', 'charmap.pyc', 'iso8859_15.pyc', 'euc_jp.py', 'cp1250.py', 'iso8859_10.pyc', 'koi8_r.pyc', 'unicode_escape.pyc', 'cp863.pyc', 'iso8859_4.pyc', 'cp852.py', 'unicode_internal.py', 'big5hkscs.py', 'cp1257.pyc', 'cp1254.py', 'shift_jisx0213.py', 'shift_jis.pyc', 'cp869.pyc', 'hp_roman8.py', 'iso8859_4.py', 'cp775.py', 'cp1251.py', 'mac_cyrillic.pyc', 'mac_greek.pyc', 'mac_roman.pyc', 'iso8859_11.pyc', 'iso8859_6.py', 'utf_8_sig.py', 'iso8859_3.py', 'iso2022_jp_1.py', 'ascii.py', 'cp1026.pyc', 'cp1250.pyc', 'cp950.py', 'raw_unicode_escape.py', 'euc_jis_2004.pyc', 'cp775.pyc', 'euc_kr.py', 'mac
_greek.py', 'big5.pyc', 'shift_jis_2004.pyc', 'gbk.pyc', 'cp1254.pyc', 'cp1255.pyc', 'cp855.pyc', 'string_escape.pyc', 'cp949.pyc', 'cp1258.pyc', 'iso8859_3.pyc', 'mac_iceland.pyc', 'cp1251.pyc', 'cp860.py', 'cp856.py', 'cp874.py', 'iso2022_kr.py', 'cp856.pyc', 'rot_13.py', 'palmos.py', 'iso2022_jp_2.pyc', 'mac_farsi.py', 'koi8_u.pyc', 'cp1256.py', 'iso8859_10.py', 'tis_620.py', 'iso8859_14.pyc', 'cp1253.py', 'cp1258.py', 'cp437.py', 'cp862.pyc', 'mac_turkish.py', 'undefined.py', 'euc_kr.pyc', 'gb18030.pyc', 'aliases.pyc', 'iso8859_9.py', 'uu_codec.py', 'gbk.py', 'quopri_codec.pyc', 'iso8859_7.py', 'mac_iceland.py', 'iso8859_2.pyc', 'euc_jis_2004.py', 'iso2022_jp_3.pyc', 'cp874.pyc', '__init__.py', 'mac_roman.py', 'iso8859_16.py', 'cp866.py', 'unicode_internal.pyc', 'mac_turkish.pyc', 'johab.pyc', 'cp037.pyc', 'punycode.py', 'cp1253.pyc', 'euc_jisx0213.pyc', 'iso2022_jp_2004.pyc', 'iso2022_kr.pyc', 'zlib_codec.pyc', 'cp932.py', 'cp1255.py', 'iso2022_jp_1.pyc', 'cp857.pyc', 'cp424.pyc',
 'iso2022_jp_2.py', 'iso2022_jp.pyc', 'mbcs.py', 'utf_8.py', 'palmos.pyc', 'cp1252.pyc', 'aliases.py', 'quopri_codec.py', 'latin_1.pyc', 'iso2022_jp.py', 'zlib_codec.py', 'cp1026.py', 'cp860.pyc', 'cp1252.py', 'hex_codec.pyc', 'iso8859_1.pyc', 'cp850.pyc', 'cp861.py', 'iso8859_15.py', 'cp865.pyc', 'hp_roman8.pyc', 'iso8859_7.pyc', 'mac_latin2.py', 'iso8859_11.py', 'mac_centeuro.pyc', 'iso8859_6.pyc', 'ascii.pyc', 'mac_centeuro.py', 'iso2022_jp_3.py', 'bz2_codec.py', 'mac_arabic.pyc', 'euc_jisx0213.py', 'tis_620.pyc', 'shift_jis_2004.py', 'utf_8.pyc', 'cp855.py', 'mac_romanian.pyc', 'iso8859_8.py', 'cp869.py', 'ptcp154.py', 'utf_16_be.py', 'iso2022_jp_ext.pyc', 'bz2_codec.pyc', 'base64_codec.py', 'latin_1.py', 'charmap.py', 'hz.pyc', 'cp950.pyc', 'cp875.pyc', 'cp1006.pyc', 'utf_16.py', 'shift_jisx0213.pyc', 'cp424.py', 'cp932.pyc', 'iso8859_5.py', 'mac_romanian.py', 'utf_8_sig.pyc', 'iso8859_1.py', 'cp875.py', 'cp437.pyc', 'cp865.py', 'utf_7.py', 'utf_16_be.pyc', 'rot_13.pyc', 'euc_jp.p
yc', 'raw_unicode_escape.pyc', 'iso8859_8.pyc', 'utf_16.pyc', 'iso8859_14.py', 'iso8859_16.pyc', 'cp852.pyc', 'cp737.pyc', 'mac_croatian.py', 'mac_latin2.pyc', 'iso2022_jp_ext.py', 'cp1140.py', 'mac_cyrillic.py', 'cp1257.py', 'cp500.py', 'cp1140.pyc', 'shift_jis.py', 'unicode_escape.py', 'cp864.py', 'cp864.pyc', 'cp857.py', 'hex_codec.py', 'mac_farsi.pyc', 'idna.py', 'johab.py', 'utf_7.pyc', 'cp863.py', 'iso8859_13.py', 'koi8_u.py', 'gb2312.pyc', 'cp1256.pyc', 'cp866.pyc', 'iso2022_jp_2004.py', 'utf_16_le.pyc', 'gb2312.py', 'cp1006.py', 'big5.py']
 

mais comme tout le monde peut enregistrer un codec, cette liste ne sera donc pas exhaustive.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X