0
点赞
收藏
分享

微信扫一扫

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

RockYoungTalk 2022-02-17 阅读 99


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
"""



举报

相关推荐

0 条评论