为什么有时候必须添加sys.setdefaultencoding('utf-8')

今天在尝试Python的CGI模块时遇到中文字符不能正确显示的问题,很郁闷.在网上仔细找了找,终于解决了这个问题,现在将解决方法陈述如下,以防下次失误.

 

页面源代码如下

#-*- coding: utf8 -*-

import cgitb , cgi
cgitb.enable()

form = cgi.FieldStorage()
if (form.has_key("name") and form.has_key("addr")):
    print "<p>name:", form["name"].value

    print "<p>addr:", form["addr"].value

[这里仅仅测试addr参数为中文]接收Ascii字符时运行良好,但是接收中文字符时显示乱码,浏览器切换到GB2312编码时

可以正常显示,但是个人要求它成为UTF-8编码显示

 

改成 print "<p>addr:", form["addr"].value.encode('utf-8')  就报如下错误:

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-1: invalid data

 

在参阅了http://blog.chinaunix.net/u2/68206/showart_668359.html 后终于理解,

Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。编码是 unicode -> str,相反的,解码就
是 str -> unicode。剩下的问题就是确定何时需要进行编码或者解码了.关于文件开头的"编码指示",也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用"编码指示"来修正. 关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。比如我有如下代码: 
#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
s = '中文'  # 注意这里的 str 是 str 类型的,而不是 unicode 
s.encode('gb18030') 

这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型的,因此 
Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是 
ANSCII,如果 s 不是这个类型就会出错。拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了: 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 
0: ordinal not in range(128) 
对于这种情况,我们有两种方法来改正错误: 
一是明确的指示出 s 的编码方式 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

s = '中文' 
s.decode('utf-8').encode('gb18030') 


二是更改 sys.defaultencoding 为文件的编码方式 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

import sys 
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入 
sys.setdefaultencoding('utf-8') 

str = '中文' 
str.encode('gb18030')

   

看完之后,改成这样

print "<p>addr:", form["addr"].value.decode('gb2312').encode('utf-8') 
成功通过.

 

我总结一下为什么要这么写的原因:

1. 当取回来的数据与你当前脚本中声明的编码不一致时就要做编码转换

2.在编码转换时首先要将该数据以自身编码的格式换成unicode码,再将这个unicode按utf8编码

3.为什么我的浏览器会传回gb2312的编码数据到服务器,这应该和客户端的系统编码有关系

 

转自:http://vb2005xu.iteye.com/blog/258633

# -*- coding: utf-8 -*- from abaqus import * from abaqusConstants import * import os def create_mapped_field(file_path='D:/temp/pressure.txt', field_name='PressureField', model_name=None): # 检查模型名称 if model_name is None: model_names = mdb.models.keys() if not model_names: raise Exception(u"未找到可用模型") model_name = model_names[0] # 默认使用第一个模型 my_model = mdb.models[model_name] # 检查文件路径 if not os.path.exists(file_path): raise Exception(u"文件不存在: %s" % file_path) data = [] with open(file_path, 'r') as f: for line_num, line in enumerate(f, 1): line = line.strip() if not line or line.startswith('#'): continue values = line.split() if len(values) != 4: print(u"警告:第{0}行格式错误,已跳过".format(line_num)) continue try: x, y, z, pressure = map(float, values) data.append((x, y, z, pressure)) except ValueError as e: print(u"第{0}行数据转换失败:{1}".format(line_num, str(e))) # 创建映射场(关键修正点) try: session.MappedField( # 必须使用 session 对象 name=field_name, description=u'压力分布场', regionType=POINT_BASED, fieldType=SCALAR, dataType=SCALAR, data=data, localCsys=None ) print(u"Mapped field '{0}' 创建成功".format(field_name)) # 缩进必须一致 except Exception as e: raise Exception(u"创建映射场失败:{0}".format(str(e))) print(u"脚本执行完毕") Abaqus/CAE 2017版本 UnicodeEncodeError: 'asci' codec can't encode characters in position 0-5: ordinal not in range(128) Dismiss
最新发布
04-03
<think>好的,我需要帮助用户解决Python中使用joblib模块时出现的UnicodeEncodeError问题。用户提到错误是ascii codec无法编码字符,特别是在resource_tracker.py文件中。我需要先理解这个错误的原因,然后找到解决办法。 首先,UnicodeEncodeError通常发生在尝试将包含非ASCII字符的字符串用ASCII编码处理时。Python默认的编码环境有时可能设置为ASCII,导致无法处理其他字符,比如中文、日文或特殊符号。用户在使用joblib进行并行处理时,如果传入的文件路径或数据包含非ASCII字符,就可能触发这个错误。 接下来,我需要回忆相关的解决方案。根据用户提供的引用,特别是引用[4]提到的设置PYTHONIOENCODING环境变量为utf-8可能有效。此外,修改Python的默认编码也是一种方法,但需要注意Python3中直接修改sys.setdefaultencoding可能不可行,因为Python3默认就是utf-8,不过在某些环境中可能需要明确设置。 另外,检查代码中的字符串处理部分是否正确使用Unicode也可能有帮助。例如,确保所有文件路径都正确编码为utf-8,或者在打开文件时指定正确的编码参数。比如在使用open函数时,加上encoding='utf-8'参数。 还有,检查系统区域设置是否正确配置为支持UTF-8有时候,操作系统的默认编码设置会影响Python的行为,尤其是在不同的终端或服务器环境中。可以通过设置环境变量LC_ALL和LANG来调整。 然后,可能需要考虑joblib本身的配置。查看joblib的文档是否有关于处理非ASCII字符的建议,或者在调用joblib的函数时传递特定的参数来避免编码问题。 总结可能的解决步骤: 1. 设置环境变量PYTHONIOENCODING为utf-8。 2. 修改系统区域设置以支持UTF-8。 3. 在代码中显式处理字符串编码,确保非ASCII字符正确编码。 4. 检查文件路径和数据处理部分是否包含非ASCII字符,并进行适当的编码转换。 5. 更新joblib到最新版本,确认是否有相关的修复。 需要验证这些方法是否有效,可能需要用户测试不同的解决方案。同时,提醒用户注意修改环境变量或默认编码可能带来的其他影响,确保不会破坏其他部分的代码。 最后,生成相关问题,帮助用户深入理解类似问题的解决方法和预防措施。</think>### 解决Python joblib UnicodeEncodeError问题的方法 #### 问题原因 当`joblib`在处理包含**非ASCII字符**(如中文、日文、特殊符号)的路径或数据时,若系统默认编码为`ASCII`,会触发`UnicodeEncodeError: 'ascii' codec can't encode characters`错误[^3][^4]。 --- #### 解决方案 1. **设置环境变量强制UTF-8编码** ```bash # 在运行Python脚本前添加环境变量 export PYTHONIOENCODING=utf-8 python your_script.py ``` 或在代码中直接指定: ```python import os os.environ["PYTHONIOENCODING"] = "utf-8" ``` 此方法覆盖默认编码配置,确保字符编码一致性[^4]。 2. **修改系统区域设置** 在终端中执行: ```bash export LC_ALL=en_US.UTF-8 export LANG=en_US.UTF-8 ``` Windows用户可通过控制面板调整系统区域设置为UTF-8支持。 3. **显式处理路径编码** 若错误由文件路径中的非ASCII字符引起,需将路径转换为`bytes`后再解码: ```python from pathlib import Path path = Path("包含中文的路径").resolve().as_posix().encode('utf-8').decode('utf-8') ``` 4. **升级joblib并检查代码** ```bash pip install --upgrade joblib ``` 确保代码中未隐式依赖ASCII编码,例如文件操作时指定`encoding='utf-8'`: ```python with open("file.txt", "r", encoding="utf-8") as f: data = f.read() ``` --- #### 示例代码修复 ```python from joblib import Parallel, delayed import os # 设置环境变量(可选) os.environ["PYTHONIOENCODING"] = "utf-8" def process_data(file_path): with open(file_path, "r", encoding="utf-8") as f: return f.read() # 确保路径使用UTF-8编码 files = ["数据/中文文件.txt".encode('utf-8').decode('utf-8')] results = Parallel(n_jobs=2)(delayed(process_data)(f) for f in files) ``` ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值