UnicodeEncodeError: 'ascii' codec can't encode character u' ' in position 20: ordinal not in range(128)

UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xa0’ in position 20: ordinal not in range(128)

技术背景

在Python编程中,UnicodeEncodeError 是一个常见的错误。当我们尝试将Unicode字符串编码为字节串(如使用 str() 函数),而Python默认使用的ASCII编码无法处理某些超出ASCII范围(0-127)的字符时,就会抛出此错误。这通常发生在处理包含非ASCII字符(如中文、特殊符号等)的字符串时。

实现步骤

1. 阅读Python官方文档

首先,可以阅读Python的 Unicode HOWTO 文档,其中这个错误是第一个示例。

2. 避免使用 str() 进行转换

不要使用 str() 函数将Unicode字符串转换为编码后的文本或字节,而是使用 .encode() 方法。例如:

1
p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()

3. 处理环境变量

确保系统的环境变量设置正确,特别是 LANGLC_ALL。可以使用以下命令进行检查和设置:

1
2
3
echo $LANG
echo $LC_ALL
export LC_ALL='en_US.utf8'

4. 安装语言包

在Linux系统中,可以安装 language-pack-en 包来提供英文翻译数据更新,确保默认的英文语言环境设置正确:

1
sudo apt-get install language-pack-en

5. 代码中指定编码

在代码中使用正确的编码,例如在打开文件时指定编码:

1
open(foo, encoding='utf-8')

6. 处理字符串

可以使用 unicodedata.normalize() 方法对字符串进行规范化处理,移除不必要的字符:

1
2
import unicodedata
message = unicodedata.normalize("NFKD", message)

核心代码

Python 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 避免使用 str() 进行转换
p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()

# 处理环境变量
import sys
reload(sys)
sys.setdefaultencoding('utf8')

# 安全字符串处理函数
def safeStr(obj):
try: return str(obj)
except UnicodeEncodeError:
return obj.encode('ascii', 'ignore').decode('ascii')
except: return ""

Python 3

1
2
3
4
5
6
7
8
9
10
# 安全字符串处理函数
def safeStr(obj):
try: return str(obj).encode('ascii', 'ignore').decode('ascii')
except: return ""

# 设置环境变量
import os
import locale
os.environ["PYTHONIOENCODING"] = "utf-8"
myLocale = locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8")

最佳实践

  • 在代码文件开头指定编码:
1
# -*- coding: utf-8 -*-
  • 尽可能在整个程序中使用Unicode字符串进行处理,只在需要与外部系统交互(如写入文件、网络传输等)时进行编码。
  • 使用 six 库编写兼容Python 2和Python 3的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
from six import PY2, iteritems

CHAR_SWAP = { u'\u201c': u'"', u'\u201D': u'"', u'\u2018': u"'", u'\u2019': u"'" }

def toAscii(text):
try:
for k, v in iteritems(CHAR_SWAP):
text = text.replace(k, v)
except: pass
try: return str(text) if PY2 else bytes(text, 'replace').decode('ascii')
except UnicodeEncodeError:
return text.encode('ascii', 'replace').decode('ascii')
except: return ""

常见问题

1. 使用 ignore 选项的风险

使用 encode('ascii', 'ignore') 会默默地丢弃所有非ASCII字符,这会导致代码失去对Unicode和国际化的支持。

2. 终端编码问题

如果终端不支持某些Unicode字符,即使代码中处理正确,仍然可能无法正确显示。可以通过设置终端的编码为UTF-8来解决。

3. Django项目部署问题

当Django项目使用Apache部署时,由于Apache在 /etc/sysconfig/httpd 中设置了 LANG=C,可能会导致此错误。可以打开该文件并注释或修改此设置,或者使用 WSGIDaemonProcess 命令的 lang 选项。


UnicodeEncodeError: 'ascii' codec can't encode character u' ' in position 20: ordinal not in range(128)
https://119291.xyz/posts/unicodeencodeerror-ascii-codec-cant-encode-character/
作者
ww
发布于
2025年6月6日
许可协议