Python中如何解决编码和系统编码不一致的问题?

情形 1 : LC_ALL="en_US.UTF-8"

>>>i=u'呵呵'

>>>i

u'\u5475\u5475'

>>>i.encode('utf-8')

'\xe5\x91\xb5\xe5\x91\xb5'

>>>type(i)

<type 'unicode'>

情形 2 : LC_ALL=C

>>> i=u'呵呵'

>>> i

u'\xe5\x91\xb5\xe5\x91\xb5' #这是什么鬼??

>>> type(i)

<type 'unicode'>

>>> i.encode('utf-8')

'\xc3\xa5\xc2\x91\xc2\xb5\xc3\xa5\xc2\x91\xc2\xb5'

唯一的区别就是 LC_ALL 了,所以谁能详细解释下这个编码与 LC_ALL 的关系呢。


Python中如何解决编码和系统编码不一致的问题?

9 回复

→python3


核心思路:统一编码为UTF-8,并在读写时明确指定。

Python 3默认用UTF-8,但处理外部数据(文件、网络、系统输出)时,编码可能不一致。关键是在数据进出程序时做好转换。

1. 处理文件读写encoding参数明确指定:

# 写入UTF-8文件
with open('file.txt', 'w', encoding='utf-8') as f:
    f.write('一些文本')

# 读取GBK编码的文件
with open('gbk_file.txt', 'r', encoding='gbk') as f:
    content = f.read()

2. 处理系统标准流(控制台) Windows控制台常用GBK,可能导致乱码。可以这样处理:

import sys, io
# 重设标准输出流编码(Windows下)
if sys.platform == 'win32':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')

print("中文字符")  # 现在应该正常显示

3. 处理字节与字符串转换 网络数据或二进制数据需要显式解码:

# 字节转字符串(已知编码)
byte_data = b'\xd6\xd0\xce\xc4'  # GBK编码的"中文"
text = byte_data.decode('gbk')   # 解码为字符串

# 字符串转字节
byte_data = text.encode('utf-8')  # 编码为UTF-8字节

4. 获取/设置系统编码

import sys, locale
print(sys.getdefaultencoding())    # Python默认编码
print(locale.getpreferredencoding())  # 系统区域编码

# 临时修改(不推荐永久修改)
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

5. 处理未知编码的数据

# 尝试多种编码(按可能性排序)
encodings = ['utf-8', 'gbk', 'gb2312', 'latin-1']
raw_bytes = b'...'  # 原始字节数据

for enc in encodings:
    try:
        text = raw_bytes.decode(enc)
        print(f"成功解码为 {enc}")
        break
    except UnicodeDecodeError:
        continue

总结:始终在数据边界处明确编码,内部统一用Unicode字符串处理。

.decode(‘gbk’)

我认为是你输入的值有了问题,不然你看看 len(i) 是怎样?

快转换到 python3 吧,别在编码问题上死磕了

Python3 没有这些问题。。

LC_ALL=C 时, Python 不知道你输入的字面量是什么编码,于是默认 ISO-8859-1 。
encode 的时候,就按 ISO-8859-1 -> UTF-8 的规则转换了。

纠正一下,是解析 u’呵呵’ 的时候把 “呵呵” 的 UTF-8 表示( E5 91 B5 E5 91 B5 )当作 ISO-8859-1 编码转换为 Unicode codepoint 序列( U+00E5 U+0091 U+00B5 U+00E5 U+0091 U+00B5 )了.
encode 的时候,就是把上面提到的那个 Unicode codepoint 序列编码成 UTF-8

回到顶部