我的编程空间,编程开发者的网络收藏夹
学习永远不晚

由 Python2 和 Python3

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

由 Python2 和 Python3

这几天在做一个功能实现的时候,需要把别人用 Python2.6 写好的脚步转成 Python3.4 实现,大部分地方转化都没啥问题,但是在 socket.inet_aton() 转化的过程中出了点问题,花费我不少的精力去解决,先做个记录备忘,同时给后续需要的人做个提醒。

首先说一下,我在解决这个问题前期的思路有点问题,所以请关注最后的总结。

需求目的:把一个 ip 地址使用 socket.inet_aton() 转化后和一个字符串组合,然后算出 MD5。

下面是 Python2.6 的实现代码:

#!python2
# -*- coding: utf-8 -*-

import socket
import hashlib

if __name__ == '__main__':
    ip = '192.168.1.12'
    base_str = 'testSTR'
    ip_md5 = hashlib.md5(socket.inet_aton(ip) + base_str).digest().encode('hex')
    print(ip_md5)

运行后的输出结果为:

fc138bb4748a18f885cc321c2c6396e2

如果原封不动的使用 Python3.4 运行后,报错如下:

Traceback (most recent call last):
  File "socket34.py", line 25, in <module>
    test1()
  File "socket34.py", line 10, in test1
    ip_md5 = hashlib.md5(socket.inet_aton(ip) + base_str).digest().encode('hex')
TypeError: can't concat bytes to str

提示说的是,socket.inet_aton(ip) 的返回值是 bytes 类型,所以不能和 str 类型的 base_str 直接进行连接操作。
也就是说 Python2.6 和 python3.4 中对于 socket.inet_aton(ip) 的实现是有差异的,查官方文档吧。
python2.6文档说明:

socket.inet_aton(ip_string)
Convert an IPv4 address from dotted-quad string format (for example, ‘123.45.67.89’) to 32-bit packed binary format, as a bytes object four characters in length.

python3.4 文档说明:

socket.inet_aton(ip_string)
Convert an IPv4 address from dotted-quad string format (for example, ‘123.45.67.89’) to 32-bit packed binary format, as a string four characters in length.

好吧,返回值类型不同,为了保证和原脚本逻辑一致,我就做个转化,把 bytes 主动转换为 str 类型再连接,修改后的代码如下:

#!python3
# -*- coding: utf-8 -*-

import socket
import hashlib

if __name__ == '__main__':
    ip = '192.168.1.12'
    base_str = 'testSTR'
    str_md5 = socket.inet_aton(ip).decode('gbk') + base_str
    ip_md5 = hashlib.md5(str_md5).digest().encode('hex')
    print(ip_md5)

代码通过 decode 把 bytes 使用 gbk 的方式解码成 str,至于为什么用 gbk,是因为我对比了下,只有 gbk 编码方式解码后的输出才和 python2.6 中的 str 返回值结果一致。

行,赶紧运行一把试试看。。。还是报错了,这次的报错内容变了:

Traceback (most recent call last):
  File "socket34.py", line 34, in <module>
    test1()
  File "socket34.py", line 12, in test1
    ip_md5 = hashlib.md5(str_md5).digest().encode('hex')
TypeError: Unicode-objects must be encoded before hashing

看起来 hashlib.md5() 在 Python2.6 和 Python3.4 中的实现也有差异,继续看文档。
python2.6文档说明:

You can now feed this object with arbitrary strings using the update() method.

python3.4 文档说明:

You can now feed this object with bytes-like objects (normally bytes) using the update() method.

依然是编码格式的问题,Python2.6 中参数传入的是 str,但是 Python3.4 中参数需要传入 bytes,那就继续转码吧。
再次转码后的代码如下:

#!python3
# -*- coding: utf-8 -*-

import socket
import hashlib

if __name__ == '__main__':
    ip = '192.168.1.12'
    base_str = 'testSTR'
    str_md5 = socket.inet_aton(ip).decode('gbk') + base_str
    ip_md5 = hashlib.md5(str_md5.encode('gbk')).digest().encode('hex')
    print(ip_md5)

运行后再次报错:

Traceback (most recent call last):
  File "socket34.py", line 33, in <module>
    test1()
  File "socket34.py", line 11, in test1
    ip_md5 = hashlib.md5(str_md5.encode('gbk')).digest().encode('hex')
AttributeError: 'bytes' object has no attribute 'encode'

好吧,继续看文档。
python2.6文档说明:

hash.digest()
Return the digest of the strings passed to the update() method so far. This is a string of digest_size bytes which may contain non-ASCII characters, including null bytes.

python3.4 文档说明:

hash.digest()
Return the digest of the data passed to the update() method so far. This is a bytes object of size digest_size which may contain bytes in the whole range from 0 to 255.

这次更严重,encode() 直接用不了,换方法吧,更新后的代码如下:

#!python3
# -*- coding: utf-8 -*-

import socket
import hashlib
import binascii

if __name__ == '__main__':
    ip = '192.168.1.12'
    base_str = 'testSTR'
    str_md5 = socket.inet_aton(ip).decode('gbk') + base_str
    ip_md5 = binascii.hexlify(hashlib.md5(str_md5.encode('gbk')).digest()).decode()
    print(ip_md5)

运行后的输出结果:

fc138bb4748a18f885cc321c2c6396e2

终于得到了最终结果,激动,不过再回头一看,如果知道这几个函数的使用方式的话,就不需要 decode() 然后又 encode(),比如稍微优化后的代码如下:

#!python3
# -*- coding: utf-8 -*-

import socket
import hashlib
import binascii

if __name__ == '__main__':
    ip = '192.168.1.12'
    base_str = 'testSTR'
    str_md5 = socket.inet_aton(ip) + base_str.encode()
    ip_md5 = binascii.hexlify(hashlib.md5(str_md5).digest()).decode()
    print(ip_md5)

总结:

  1. Python3 新增了 bytes 类型,对于 bytes 的转换逻辑要特别清楚,这地方涉及了编码类型,要特别关注;
  2. 在使用一些函数前,一定要搞清楚这个函数的具体实现,必须清楚的知道使用了这个函数是什么效果,而不仅仅是看到暂时的效果,或者经验主义的去调用(上面例子的最后一步,其实我一开始不是用的 binascii,而是用的现成的 md5 转换函数,导致 encode() 成了 utf-8 格式,而浪费了不少时间去定位);
  3. 解决问题过程中,思路一定要清晰,不能靠猜,越猜越错;
  4. 先弄明白问题的根本原因,直接从根源上去解决,比一步步的就错解错,效果更好。

本文原创发布于公众号「sylan215」,十年测试老兵的原创干货,关注我,涨姿势!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

由 Python2 和 Python3

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

由 Python2 和 Python3

这几天在做一个功能实现的时候,需要把别人用 Python2.6 写好的脚步转成 Python3.4 实现,大部分地方转化都没啥问题,但是在 socket.inet_aton() 转化的过程中出了点问题,花费我不少的精力去解决,先做个记录备忘
2023-01-31

Python2 和 Python3 的

前言最近 Python 之父 Guido van Rossum(龟爷)终于在 Python 官方邮件组落实了 Python 2.7 的终焉之日(EOL)。说的是 Python 2.7 的 EOL 日期最终确定为 2020 年 1 月 1 日
2023-01-31

Python2 和 Python3 中默

最近在使用 Python3.4 做一些脚本实现,发现对于编码的处理上和 Python2.6 有很大的不同,就此机会把相关知识做个梳理,方便需要的时候查阅。先说下概念和差异:脚本字符编码:就是解释器解释脚本文件时使用的编码格式,可以通过 #
2023-01-31

python2和python3的区别

1.性能 Py3.0运行 pystone benchmark的速度比Py2.5慢30%。Guido认为Py3.0有极大的优化空间,在字符串和×××操作上可 以取得很好的优化结果。 Py3.1性能比Py2.5慢15%,还有很大的提升空间。 2
2023-01-31

python3 和 python2的区别

python2python31. Python3对Unicode字符的原生支持。Python2中使用 ASCII 码作为默认编码方式导致string有两种类型str 和unicode,Python3只支持unicode的string。Pyt
2023-01-31

python2.x和python3.x的

Python的3​​.0版本,常被称为Python3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python3.0在设计的时候没有考虑向下相容。许多针对早期Python版本设计的程式都无法
2023-01-31

Python3.x和Python2.x的

1.性能 Py3.0运行 pystone benchmark的速度比Py2.5慢30%。Guido认为Py3.0有极大的优化空间,在字符串和×××操作上可 以取得很好的优化结果。 Py3.1性能比Py2.5慢15%,还有很大的提升空间。 2
2023-01-31

python2.x和python3.x共

下载python2.x和python3.x安装在同一目录下不同的文件夹配置环境变量(我是安装在F盘下)1.F:\Python272.F:\Python27\Scripts3.F:\Python334.F:\Python33\Scripts理
2023-01-31

python3 vs python2

一、print,在python3中已经是函数>>> import sys>>> print("fatal error",file=sys.stderr)fatal error>>> fp=open(r"d:\\a.txt",'w')>>>
2023-01-31

Python2和Python3的区别,以

学习Python 2还是Python 3?罗振宇在今年的跨年演讲,《时间的朋友》中有个观点,大意是说,人们都有一种受虐情节,有时候希望别人对他粗暴一点。为此,他还举了两个例子,分别是“乔布斯对待消费者的态度”和“和菜头不尊重他的饮食需求”,
2023-01-31

转:python3和Python2的区别

print函数:(Python3中print为一个函数,必须用括号括起来;Python2中print为class)Python 2 的 print 声明已经被 print() 函数取代了,这意味着我们必须包装我们想打印在小括号中的对象。Py
2023-01-31

Python3 vs. Python2

导读:哪个版本的 Python 最快?Python 3 真的比 Python 2 慢吗?Python 3 最快的版本是哪个?......当然,这些问题由多种因素决定,其中的主要的因素是什么呢?我们又如何为自己的应用寻找最快的 Python
2023-01-31

Python2和Python3选择哪个好

这篇文章主要介绍“Python2和Python3选择哪个好”,在日常操作中,相信很多人在Python2和Python3选择哪个好问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python2和Python3选择
2023-06-02

Python2的input(), raw_input()和Python3的input()

前言现在来探讨一下Python2中的input()、raw_input()函数和Pyhont3中的input()函数:Python2中的raw_input()函数,我们知道input()、raw_input()都是让用户输入的函数:inpu
2023-06-02

Python3和Python2有什么不同

今天就跟大家聊聊有关Python3和Python2有什么不同,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、打印时,py2需要可以不需要加括号,py3 需要python 2 :pr
2023-06-15

python2和python3的一些差别

未来python3是主流,但还是因为一部分原因,很多项目还在用python2。python3是不兼容python2的,做了一些优化和改进1.字符编码  python2:ascii编码  python3:unicode编码(默认utf-8)2
2023-01-30

python2和python3有什么区别

python2和python3有什么区别?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向对象
2023-06-14

用python2和python3伪装浏览

python网页抓取功能非常强大,使用urllib或者urllib2可以很轻松的抓取网页内容。但是很多时候我们要注意,可能很多网站都设置了防采集功能,不是那么轻松就能抓取到想要的内容。今天我来分享下载python2和python3中都是如何
2023-01-31

Python2和Python3的一些语法

pythonPython2和Python3的一些语法区别1.print2.input3. python3版本相对2版本的部分其他区别问题:为何会出现乱码的情况问题:如何获取编码方式的信息?问题:在控制台上看到的到底是什么?1.print在版
2023-01-31

Python3 和 Python2 有什么区别

这篇文章给大家介绍Python3 和 Python2 有什么区别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Python3和Python2相比:1、Python3去除print语句,加入print()函数实现相同的功
2023-06-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录