项目从pyhon2.7升级到python3.9

一、看项目引用了哪些开源模块#####

我们项目我捋了一遍用了三个开源:

  1. pyzmq
  2. pyserial
  3. gdb

前两个直接在源码中(随便哪个入口文件头部一般会注释开源信息),找到对应的github地址,我是先自己在电脑上用pip3安装的(命令 pip3 install pyzmq/pyserial),安装完了后, 在路径
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/serial
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/zmq
找到这两个文件夹,然后拷贝到项目,就搞定了。

第三个gdb,没用到python,只是借用了它batch功能,所以不用升级,兼容python3.

开源模块升级完后,记得从原有项目中提出来,开始对剩下的文件进行第二步动作。

二、采用2to3工具

参考这篇文章,讲的很详细
2to3 - 自动将 Python 2 代码转为 Python 3 代码
就在终端使用命令

2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode

我使用该命令是这样的

2to3 --output-dir=ph1_Script_Python3.0/ -w -n ph1_Script_Python3.0/

这样转换出来的包总是报 ImportError: attempted relative import with no known parent package的问题,这是因为2to3工具将项目import默认转成了相对地址,所以我增加了一个参数 -f all -x import ,让2to3不要把项目的import转成相对路径,修改后命令如下

2to3 -f all -x import --output-dir=ph1_Script_Python3.0/ -w -n ph1_Script_Python3.0/

这样转换出来就没有impor的问题了,然后对项目不是特别熟,所以将可选的修复器全部都选上了,最后执行的命令是这样的

2to3 -f all -x import -f buffer -f idioms -f set_literal -f ws_comma --output-dir=ph1_Script_Python3.0/ -w -n ph1_Script_Python3.0/

三、微调

前两个步骤将项目已经完全升级成python3.0版本了,接下来就是看build的时候会出什么问题,针对性的解决,就我项目而言,出现了以下几个问题

  1. .encode('string-escape' )
    python2
addLog("diag:{}".format(totalRes.encode('string-escape')))

python3

# addLog("diag:{}".format(totalRes.encode('latin1').decode('unicode-escape').encode('latin1')))
  1. exception.message
    Python2.7
try:
        main()
except Exception as ex:
        ex.message = "Software error-" + str(ex)
        OutputExceptAndExit(ex)
...
output = ex.message

Python3.9

try:
        main()
except Exception as ex:
        ex.args = ex.args+("Software error-" + str(ex),)
        OutputExceptAndExit(ex)
...
output = repr(ex)

python2的try exception和python3的区别如下


image.png
  1. python2 subprocess 函数返回值都是string
    python2
p1 = Popen(helloGDB, stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = True)

python3

p1 = Popen(helloGDB, stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = True, universal_newlines=True)

python3 subprocess的返回值默认都是bytes,所以在创建subprocess对象的时候传入参数universal_newlines=True,让返回值都为string,从而改动比较小

  1. python3的pyserial函数传入的参数都要求是bytes

python2

 self.port.write(cmd)
res = self.port.read_until(terminator)

python3

self.port.write(cmd.encode())
res_bytes = self.port.read_until(terminator)
        res = str(res_bytes, encoding="utf-8")
  1. Python2和3的除法不一样
    Python2.x 里,整数除整数,只能得出整数
    a = 10 ,b = 20,b / a的运行结果是2.0,所得结果是浮点型
    所以有计算出来的结果给range(a)用到了,都要做一下处理range(int(a))
image.png
  1. python2和3的取bin file文件的数据返回的类型不一样
    python2取出来的是string,但是python3直接返回的是int型,所以python2取出来的值还需要用ord(a)转换成int型,到了python3再这样做会报错
    TypeError('ord() expected string of length 1, but int found'), 所以在python3要把ord函数去掉
python3.png
python2.png
  1. python2和3 在bytes截取的返回值上不一致
    python2 返回的是string
    python3 返回的是bytes


    image.png
  2. python2和3 在bytes的print的format不一致
    python2
    a = b'4000\r\n'
    print('Reply:{}'.format(a))
    自动将bytes解码成string了
    但是python3还要再进行一步解码才能达到一样的效果
    print('Reply:{}'.format(str(a, encoding="ISO-8859-1")))

image.png

How do I .decode('string-escape') in Python 3? [duplicate]

你可能感兴趣的:(项目从pyhon2.7升级到python3.9)