如何在Python中将字符串转换为UTF-8

241

我有一个浏览器将UTF-8字符发送到我的Python服务器,但是当我从查询字符串中检索时,Python返回的编码是ASCII。如何将普通字符串转换为UTF-8?

注意:从web传递的字符串已经使用UTF-8编码,我只想让Python将其视为UTF-8而不是ASCII。


1
请尝试此链接:http://evanjones.ca/python-utf8.html - Mudassir
我认为更好的标题应该是“如何在不进行翻译的情况下将字符串强制转换为Unicode?” - boatcoder
3
2018年,如果在Python 3中遇到ASCII解码错误,请使用"some_string".encode('utf-8').decode('utf-8')进行处理。 - devssh
13个回答

314

在Python 2中

>>> plain_string = "Hi!"
>>> unicode_string = u"Hi!"
>>> type(plain_string), type(unicode_string)
(<type 'str'>, <type 'unicode'>)

^ 这就是字节字符串(plain_string)和 Unicode 字符串之间的区别。

>>> s = "Hello!"
>>> u = unicode(s, "utf-8")

^ 转换为Unicode并指定编码。

在Python 3中

所有字符串都是Unicode格式。 unicode 函数已经不存在了。请参考 @Noumenon 的答案。


37
我遇到了以下错误: UnicodeDecodeError: 'utf8' codec can't decode byte 0xb0 in position 2: invalid start byte 这是我的代码: ret=[]for line in csvReader: cline=[] for elm in line: unicodestr = unicode(elm, 'utf-8') cline.append(unicodestr) ret.append(cline) - Gopakumar N G
131
这些都不适用于Python 3,所有的字符串都是Unicode编码,而unicode()函数也不存在。 - Noumenon
1
如何将 u 转换回 str 格式(将 u 转换回 s)? - Tanguy
3
只要文本不包含非ASCII字符,这段代码就可以正常运行;如果字符串中有一个简单的重音字符,它就会失败。 - Haroldo_OK
1
你好,如果你有一个字符串变量包含“2340”,并且想要打印出Unicode字符U+2340(⍀),有没有什么方法可以实现呢? - Sha2b
显示剩余2条评论

83

如果以上方法不能解决问题,你也可以告诉Python忽略它无法转换为utf-8的字符串部分:

stringnamehere.decode('utf-8', 'ignore')

35
出现 AttributeError: 'str' object has no attribute 'decode' 错误。 - saran3h
3
看起来你正在使用Python 3,那么Python 应该为您处理编码问题。您是否尝试过在不指定编码的情况下读取文档? @saran3h - duhaime
4
Python默认选择系统编码。在Windows 10中,它是cp1252而不是utf-8。我在使用py 3.8中的codecs.open()时浪费了几个小时。 - Vishesh Mangla

24

可能有点过头了,但是当我在同一个文件中同时使用ascii和unicode编码时,重复解码会很麻烦,这就是我使用的方法:

def make_unicode(inp):
    if type(inp) != unicode:
        inp =  inp.decode('utf-8')
    return inp

4
这段代码已经失效了...在Python3中,unicode类型已经不存在了。 - Mike Pennington

16

在您的.py文件顶部添加以下行:

# -*- coding: utf-8 -*-

允许您直接在脚本中编码字符串,就像这样:

utfstr = "ボールト"

2
这不是 OP 所要求的。但无论如何都要避免使用这样的字符串字面量。它会在 Python 3 中创建 Unicode 字符串(好),但在 Python 2 中却是一个字节字符串(坏)。要么在顶部添加 from __future__ import unicode_literals,要么使用 u'' 前缀。不要在 bytes 字面量中使用非 ASCII 字符。如果需要,可以稍后使用 utf8bytes = unicode_text.encode('utf-8') 来获取 utf-8 字节。 - jfs
1
@jfs,from __future__ import unicode_literals会如何帮助我将包含非ASCII字符的字符串转换为UTF-8? - Ortal Turgeman
@OrtalTurgeman 我并没有回答这个问题。看,这是一条评论,而不是答案。我的评论解决了答案中代码的问题。它试图在Python 2中创建一个带有非ASCII字符的字节串(在Python 3中这是SyntaxError - 字节文字禁止这样做)。 - jfs

13
city = 'Ribeir\xc3\xa3o Preto'
print city.decode('cp1252').encode('utf-8')

13

如果我理解正确,你的代码中有一个使用utf-8编码的字节字符串。

将字节字符串转换为Unicode字符串称为解码(Unicode -> 字节字符串是编码)。

你可以使用unicode函数或decode方法来完成。两种方法都可以:

unicodestr = unicode(bytestr, encoding)
unicodestr = unicode(bytestr, "utf-8")
或者:
unicodestr = bytestr.decode(encoding)
unicodestr = bytestr.decode("utf-8")

12

在Python 3.6中,它们没有内置的unicode()方法。字符串默认已经存储为unicode,不需要转换。例如:

my_str = "\u221a25"
print(my_str)
>>> √25

5
使用ord()和unichar()进行翻译。 每个Unicode字符都有一个相应的数字,类似于索引。因此Python有一些方法可以在字符和其数字之间进行转换。不足之处是ñ的例子。希望这可以帮助您。
>>> C = 'ñ'
>>> U = C.decode('utf8')
>>> U
u'\xf1'
>>> ord(U)
241
>>> unichr(241)
u'\xf1'
>>> print unichr(241).encode('utf8')
ñ

5

将URL转换为ASCII编码后,对于Python服务器而言,它只是一个Unicode字符串,例如:"T%C3%A9st%C3%A3o"。

Python将“é”和“ã”视为实际的%C3%A9和%C3%A3。

您可以像这样对URL进行编码:

import urllib
url = "T%C3%A9st%C3%A3o"
print(urllib.parse.unquote(url))
>> Téstão

请参考https://www.adamsmith.haus/python/answers/how-to-decode-a-utf-8-url-in-python 了解如何在Python中解码UTF-8 URL。

3
  • 首先,在Python中,str是用 Unicode 表示的。
  • 其次,UTF-8 是一种编码标准,用于将 Unicode 字符串编码为 bytes。有许多编码标准可供选择(例如 UTF-16ASCIISHIFT-JIS 等)。

当客户端使用 UTF-8 发送数据到您的服务器时,它们发送的是一堆 bytes,而不是 str

您收到了一个 str,因为您正在使用的“库”或“框架”已经将一些随机的 bytes 隐式转换为 str

在底层,只有一堆 bytes。您只需要要求“库”以 bytes 的形式提供请求内容,然后您将自己处理解码(如果库无法提供,则可能存在黑魔法,您不应该使用它)。

  • UTF-8 编码的 bytes 解码为 strbs.decode('utf-8')
  • str 编码为 UTF-8bytess.encode('utf-8')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接