web-dev-qa-db-fra.com

Utilisation des fonctions unicode () et encode () dans Python

J'ai un problème avec l'encodage de la variable chemin et l'insertion dans la base de données SQLite. J'ai essayé de le résoudre avec encoder ("utf-8") fonction qui n'a pas aidé. Ensuite, j'ai utilisé la fonction nicode () qui me donne le type nicode.

print type(path)                  # <type 'unicode'>
path = path.replace("one", "two") # <type 'str'>
path = path.encode("utf-8")       # <type 'str'> strange
path = unicode(path)              # <type 'unicode'>

Finalement j'ai gagné le type nicode, mais j'ai toujours la même erreur qui était présente lorsque le type de la variable chemin était str

sqlite3.ProgrammingError: vous ne devez pas utiliser de chaînes d'octets de 8 bits à moins d'utiliser un text_factory pouvant interpréter des chaînes d'octets de 8 bits (comme text_factory = str). Il est fortement recommandé de basculer simplement votre application vers des chaînes Unicode.

Pourriez-vous m'aider à résoudre cette erreur et expliquer l'utilisation correcte des fonctions encode("utf-8") et unicode()? Je me bats souvent avec.

MODIFIER:

Cette déclaration execute () a généré l'erreur:

cur.execute("update docs set path = :fullFilePath where path = :path", locals())

J'ai oublié de changer l'encodage de la variable fullFilePath qui souffre du même problème, mais je suis assez confus maintenant. Devrais-je utiliser uniquement nicode () ou encoder ("utf-8") ou les deux?

Je ne peux pas utiliser

fullFilePath = unicode(fullFilePath.encode("utf-8"))

parce qu'il soulève cette erreur:

UnicodeDecodeError: le codec 'ascii' ne peut pas décoder l'octet 0xc5 en position 32: l'ordinal n'est pas dans la plage (128)

Python la version est 2.7.2

79
xralf

Vous utilisez encode("utf-8") de manière incorrecte. Python les chaînes d'octets (str type) ont un codage, mais pas Unicode. Vous pouvez convertir une chaîne Unicode en chaîne d'octets Python à l'aide de uni.encode(encoding) et vous pouvez convertir une chaîne d'octets en chaîne Unicode en utilisant s.decode(encoding) (ou de manière équivalente, unicode(s, encoding) ).

Si fullFilePath et path sont actuellement de type str, vous devez déterminer comment ils sont codés. Par exemple, si le codage actuel est utf-8, vous utiliseriez:

path = path.decode('utf-8')
fullFilePath = fullFilePath.decode('utf-8')

Si cela ne résout pas le problème, le problème réel peut être que vous n'utilisez pas de chaîne Unicode dans votre appel execute(), essayez de le modifier comme suit:

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
84
Andrew Clark

str est une représentation textuelle en octets, unicode est une représentation textuelle en caractères.

Vous décodez du texte d'octets en unicode et codez un unicode en octets avec un certain encodage.

C'est:

>>> 'abc'.decode('utf-8')  # str to unicode
u'abc'
>>> u'abc'.encode('utf-8') # unicode to str
'abc' 
117
newtover

Assurez-vous que vous avez bien défini vos paramètres régionaux avant d'exécuter le script à partir du shell, par exemple.

$ locale -a | grep "^en_.\+UTF-8"
en_GB.UTF-8
en_US.UTF-8
$ export LC_ALL=en_GB.UTF-8
$ export LANG=en_GB.UTF-8

Docs: man locale, man setlocale.

1
kenorb