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

本文详细解析Python CGI模块处理中文字符时出现乱码的原因及解决方案,涉及编码转换原理,如从GB2312到UTF-8的转换,以及在Python中如何正确地进行编码和解码操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在尝试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

 

在参阅了 https://www.cnblogs.com/guosq/p/6378639.html 后终于理解,

在python中,编码解码其实是不同编码系统间的转换,默认情况下,转换目标是Unicode,即编码unicode→str,解码str→unicode,其中str指的是字节流,而str.decode是将字节流str按给定的解码方式解码,并转换成utf-8形式,u.encode是将unicode类按给定的编码方式转换成字节流str。注意调用encode方法的是unicode对象,生成的是字节流;调用decode方法的是str对象(字节流),生成的是unicode对象。若str对象调用encode会默认先按系统默认编码方式decode成unicode对象再encode,忽视了中间默认的decode往往导致报错。

剩下的问题就是确定何时需要进行编码或者解码了.关于文件开头的"编码指示",也就是 # -*- 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的编码数据到服务器,这应该和客户端的系统编码有关系

 

Python操作MySQL以及中文乱码的问题

下面几个措施,保证MySQL的输出没有乱麻:
  1 Python文件设置编码 utf-8 (文件前面加上 #encoding=utf-8)
  2 MySQL数据库charset=utf-8 
  3 Python连接MySQL是加上参数 charset=utf8 
  4 设置Python的默认编码为 utf-8 (sys.setdefaultencoding(utf-8)

#encoding=utf-8  
import sys  
import MySQLdb  
  
reload(sys)  
sys.setdefaultencoding('utf-8')  
  
db=MySQLdb.connect(user='root',charset='utf8')  
cur=db.cursor()  
cur.execute('use mydb')  
cur.execute('select * from mytb limit 100')  
  
f=file("/home/user/work/tem.txt",'w')  
  
for i in cur.fetchall():  
    f.write(str(i))  
    f.write(" ")  
  
f.close()  
cur.close()  

原文: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值