前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python3编码与mysql编码介绍

Python3编码与mysql编码介绍

作者头像
YG
发布2018-05-23 17:24:00
2.1K0
发布2018-05-23 17:24:00
举报
文章被收录于专栏:YG小书屋YG小书屋

Python3自诩解决了编码问题,但还是有一系列的坑。本文就记录下前几天遇到的python3编码问题。mysql编码问题附带介绍。

python3 json串的编码

针对于包含中文的字典,如果想要正常显示中文,在dumps时,需配置参数ensure_ascii=False。举例:

代码语言:javascript
复制
a={"name":"中国"}
json.dumps(a)
'{"name": "\\u4e2d\\u56fd"}'
json.dumps(a,ensure_ascii=False)
'{"name": "中国"}'

针对于包含特定转义字符的字符串,如果想要正常解析,需要在loads时配置strict=False。举例:

代码语言:javascript
复制
json.loads('{"foo":"bar\nbaz"}')
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    json.loads('{"foo":"bar\nbaz"}')
  File "C:\Users\jonyguo\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "C:\Users\jonyguo\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\jonyguo\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Invalid control character at: line 1 column 12 (char 11)

json.loads('{"foo":"bar\nbaz"}', strict=False)
{'foo': 'bar\nbaz'}

python3的字符串编码

python3中只有两种字符串,一是str,一是bytes。str经过encode变成bytes,bytes经过decode变成str。 有时从网络取出的包含中文的数据为unicode编码的字符串,可通过先编码在解码转化为中文:

代码语言:javascript
复制
a="\\u4e2d\\u56fd"
print(a)
\u4e2d\u56fd
a.encode().decode("unicode_escape")
'中国'

也可以通过repr将其转化为字符串,将两个反斜杠替换为一个反斜杠来解决这个问题:

代码语言:javascript
复制
a="\\u4e2d\\u56fd"
eval(repr(a).replace('\\\\', '\\'))
'中国'

python3 + apache的字符编码问题

python3脚本作为cgi供前端界面调用。遇到了一个很奇怪的问题,我通过编写的python脚本调用cgi时,编码一切正常,但是当我通过http调用时会出现一些问题。从数据库中取中文数据,返回前端显示一切都正常。但是当我把数据库中的中文与一些字符组成一个文件名,判断文件是否存在时,一直报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 46-49: ordinal not in range(128)。 刚开始以为是apache的编码问题,后来查看apache的编码也确定是utf8,不知所措。经google,查找到了原因。 https://www.raspberrypi.org/forums/viewtopic.php?t=65257 这个帖子里面有介绍到说:

The difference is that from the command line Python inherits your locale settings (probably LANG=fr_FR.UTF-8), whereas from Apache it inherits LANG=C. It knows that your strings are Unicode, but it can not print them in an ASCII environment.

说是通过python脚本调用的时候python继承的是locale 设置,为utf8,可正常显示(个人感觉这里可能说的有些不恰当,这里应该是采用python3自己的编码)。而apache继承的是LANG=C,为ascii,无法正常显示。按照其配置,在/etc/apache2/envvars中添加. /etc/default/locale(/etc/sysconfig/i18n)即可。配置后发现依然无法解决问题。 后又继续google,找到了解决方案。 https://stackoverflow.com/questions/9322410/set-encoding-in-python-3-cgi-scripts

代码语言:javascript
复制
Add PassEnv LANG line to the end of your /etc/apache2/apache2.conf or .htaccess.
Uncomment . /etc/default/locale line in /etc/apache2/envvars.
Make sure line similar to LANG="en_US.UTF-8" is present in /etc/default/locale.

就是在apache2的配置文件中添加一行:PassEnv LANG 即可。要确保LANG为utf8。

mysql编码问题

查看当前的数据库编码:

代码语言:javascript
复制
mysql> show variables like 'character%';
+--------------------------+--------------------------------------------------------------+
| Variable_name            | Value                                                        |
+--------------------------+--------------------------------------------------------------+
| character_set_client     | latin1                                                       |
| character_set_connection | latin1                                                       |
| character_set_database   | utf8                                                         |
| character_set_filesystem | binary                                                       |
| character_set_results    | latin1                                                       |
| character_set_server     | latin1                                                       |
| character_set_system     | utf8                                                         |
| character_sets_dir       | /usr/local/mysql-5.1.46-linux-x86_64-glibc23/share/charsets/ |
+--------------------------+--------------------------------------------------------------+

从上图可知,数据库的编码为utf8.

● character_set_client:无论客户端传递的是什么编码的数据,服务器都当成该编码来处理,例如该编码为UTF8,那么如果客户端发送过来的数据不是UTF8,那么就会出现乱码;

● character_set_connection:通过该编码与client一致!该编码不会导致乱码!当执行的是查询语句时,客户端发送过来的数据会先转换成connection指定的编码。但只要客户端发送过来的数据与client指定的编码一致,那么转换就不会出现问题;

● character_set_database:数据库默认编码,在创建数据库时,如果没有指定编码,那么默认使用database编码;

● character_set_filesystem:可以理解为文件的最终存储形式,是二进制形式的;

● character_set_server:MySQL服务器默认编码;

● character_set_results:MySQL会把数据转换成该编码后,再发送给客户端,例如该编码为UTF8,那么如果客户端不使用UTF8来解读,那么就会出现乱码,说明客户端必须使用result指定的编码来解码;

一条数据库连接的过程如下: client --> connection --> server --> connection --> result 其实只要保证client、connection和result 一致就不会出现乱码问题。

通过set names utf8 保证client、connection和result 的编码一致:

代码语言:javascript
复制
mysql> show variables like 'character%';
+--------------------------+--------------------------------------------------------------+
| Variable_name            | Value                                                        |
+--------------------------+--------------------------------------------------------------+
| character_set_client     | utf8                                                         |
| character_set_connection | utf8                                                         |
| character_set_database   | utf8                                                         |
| character_set_filesystem | binary                                                       |
| character_set_results    | utf8                                                         |
| character_set_server     | latin1                                                       |
| character_set_system     | utf8                                                         |
| character_sets_dir       | /usr/local/mysql-5.1.46-linux-x86_64-glibc23/share/charsets/ |
+--------------------------+--------------------------------------------------------------+
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.03.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • python3 json串的编码
  • python3的字符串编码
  • python3 + apache的字符编码问题
  • mysql编码问题
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档