Python编程:Python2编码问题与pymysql查询结果乱码解决-阿里云开发者社区

开发者社区> 程序猿v> 正文

Python编程:Python2编码问题与pymysql查询结果乱码解决

简介: Python编程:Python2编码问题与pymysql查询结果乱码解决
+关注继续查看

订阅专栏

Python2编码一直是个让人头疼的问题,能够让一个充满激情的新手,从刚安装完python解释器到放弃。

我就曾经放弃过,后来又拿了起来,真是一波多折。


so,如果可能就尽量使用Python3吧


下面我就python2通过pymysql处理查询结果为例说明


要查询的数据表(包含中文)

mysql> use demo
mysql> select * from names limit 3;
+----+--------+------+
| id | name   | age  |
+----+--------+------+
|  1 | 大红   |   24 |
|  2 | 大壮   |   24 |
|  3 | 秀英   |   24 |
+----+--------+------+

python2原始代码


from collections import namedtuple
import pymysql

db = pymysql.Connect(
    host="localhost",
    user="root",
    password="123456",
    database="demo",
    port=3306
)

sql = "select name, age from names limit 3"

cursor = db.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
cursor.close()
db.close()

print(rows)


Row = namedtuple("Row", ["name", "age"])
rows = map(Row._make, rows)

for row in rows:
    person = "{}{}".format(row.name, row.age)
    print(person)

1、SyntaxError: Non-ASCII character

看着好好的代码,莫名其妙的来个语法错误SyntaxError: Non-ASCII character

SyntaxError: Non-ASCII character '\xe5' in file text.py on line 56, 
but no encoding declared; 
see http://python.org/dev/peps/pep-0263/ for details

根据报错提示的链接: http://python.org/dev/peps/pep-0263/

打开后发现需要在文件头加文件编码说明

# coding=utf-8

或者

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

2、中文变成了?

添加完文件编码后,继续运行代码,代码文件中有print(rows)print(person)打印出来的内容分别是:

(('??', 24), ('??', 24), ('??', 24))

??24
??24
??24

what? 查看pymysql.Connect 的源码,发现有一个参数charset字符集,那么添加一个字符编码试试

db = pymysql.Connect(
    host="localhost",
    user="root",
    password="123456",
    database="demo",
    port=3306,
    
    # 添加字符编码
    charset="utf8"
)

3、UnicodeEncodeError

添加完编码字符集参数后,运行又报错了!

((u'\u5927\u7ea2', 24), (u'\u5927\u58ee', 24), (u'\u79c0\u82f1', 24))

Traceback (most recent call last):
  File "text.py", line 37, in <module>
    person = "{}{}".format(row.name, row.age)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

发现print(rows)已经打印了,而且没有?,前面带u,说明是unicode字符

报错代码是:person = "{}{}".format(row.name, row.age),使用format格式化报错

明明已经在文件开头指定了文件的编码是utf-8了,怎么还是说unicode呢?

百思不得其解,经过百度,google,发现只用添加以下代码就行:

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

或者

from __future__ import unicode_literals

推荐使用后者

参考

1.https://stackoverflow.com/questions/3828723/why-should-we-not-use-sys-setdefaultencodingutf-8-in-a-py-script

2.https://stackoverflow.com/questions/9942594/unicodeencodeerror-ascii-codec-cant-encode-character-u-xa0-in-position-20

运行代码文件,发现输出正常了

((u'\u5927\u7ea2', 24), (u'\u5927\u58ee', 24), (u'\u79c0\u82f1', 24))

大红24
大壮24
秀英24

当然,直接打印整个元组对象是不能直观的看到内容的,打印出来的是unicode码,而python3就可以

总结

好了,一路过来解决3个编码问题,都需要设置编码为utf-8

报错

解决示例
SyntaxError: Non-ASCII character文件编码# -*- coding: utf-8 -*-

中文变成了?

数据库连接编码charset="utf8"
UnicodeEncodeError引入py3的新特性from __future__ import unicode_literals

注意,pymysql的编码设置charset="utf8"中间没有-

python2中的编码问题基本可以用以下两行代码解决

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

给出最后的完整代码

# -*- coding: utf-8 -*-

# @Date    : 2018-12-20
# @Author  : Peng Shiyu

from __future__ import unicode_literals
from collections import namedtuple
import pymysql

db = pymysql.Connect(
    host="localhost",
    user="root",
    password="123456",
    database="demo",
    port=3306,
    charset="utf8"
)

sql = "select name, age from names limit 3"

cursor = db.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
cursor.close()
db.close()

print(rows)


Row = namedtuple("Row", ["name", "age"])
rows = map(Row._make, rows)

for row in rows:
    person = "{}{}".format(row.name, row.age)
    print(person)

"""
((u'\u5927\u7ea2', 24), (u'\u5927\u58ee', 24), (u'\u79c0\u82f1', 24))

大红24
大壮24
秀英24
"""


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Python编程:MySQLdb模块的安装
Python编程:MySQLdb模块的安装
22 0
Python各版本冲突解决方案
之前电脑安装了anaconda,又安装了python3。anaconda的各环境相互不冲突,很好管理,确实是很方便。但今天想用下之前安装的python3,但在命令行安装库的时候,发现默认情况下是安装到anaconda中的,我尝试输入python,发现果然是这样的,如图。
963 0
Python编程:reload热更新代码
Python编程:reload热更新代码
19 0
JavaWeb项目的中文乱码的原因以及Servlet中处理GET请求和POST请求编码过滤器
一、乱码原因 ①传输方和接收方采用的编码不一致。传输方对参数采用的是UTF-8编码而接收方却用GBK进行解析,当然是乱码。 ②Tomcat服务器默认采用的ISO8859-1编码得到参数值。虽然①中采用了同样的编码方式,但经过tomcat一处理,也会出现乱码(GET方式)   二、解决办法 方法一 每次传输都手动设置编码(GET方式传输数据) 传输方 String name =
1284 0
mysql解决乱码问题
应用场景 在使用mysql数据库的过程中,发现数据导入后中文出现乱码,数据库中出现文字乱码等等,sql语句中查询中文无法查出结果,影响系统使用,以及数据无法正确查询。
686 0
python3实现域名查询和whois查询
关键字:python3 域名查询 域名查询接口 whois查询原文:http://www.cnblogs.com/txw1958/archive/2012/08/31/python3-domain-whois.
2449 0
+关注
1569
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载