美文网首页我爱编程
从python2向python3迁移

从python2向python3迁移

作者: wangrui927 | 来源:发表于2018-03-16 14:52 被阅读0次

    从2019年底,python官方将正式结束对python2的支持。而python中一些比较火热的项目,如numpy、django2都已经放弃了对python2的更新支持。python3相比较python2的改变还是比较大的,应该从现在开始就慢慢养成新的编码习惯。

    1,获取迭代器:
    在python2中,比如打开一个文件之后,可以对file对象 使用其iter()获取其内容的生成器,在触发StopIteration异常之前,每次使用next()都可以获取到一条数据。而在python3中,通过这样的方式获取其生成器后,会发现没有next()方法,只有read()方法。
    除了打开文件外,一般我在取influxdb的搜索结果时,也比较习惯使用生成器的方式(get_points()方法)

    2,路径的获取与处理
    如果涉及到python代码与本地文件的交互,那么必不可少要使用os.path方法。而在python3,官方提供了pathlib模块,其pathlib.Path则含有一系列与路径相关的操作。比如exists() is_dir() with_name()//用于修改文件名称 with_suffix()// 改变文件扩展名 chmod(mode) rmdir()

    3,类型提示
    这一项变化非常有意思,python之所以在科学计算、运维等方面有广泛的应用,一个最重要的原因,就是作为胶水、脚本语言使用时,编写起来非常快速。你不需要考虑太多数据类型的问题,可以把注意力放在业务逻辑上。
    起初我也不是理解java如此复杂的框架,代码中光数据相关的内容就有很多。但随着工作经验积累,我逐渐明白——有时候太自由反而带来很多麻烦。
    在python3,可以指定函数参数的类型,比如:

    class easy_cal:
            def __init__(self, numa: int, numb: int):
                self.a = numa
                self.b = numb
    

    这样如果你输入错误的内容,就会返回类型错误的提示。类型提示可以帮助我们更好的开发一些复杂大型的项目。
    我也想展开抒发一点自己的看法,python之所以吸引人,就是因为一个数学家只需要花半天或者一天的时间,就能大致掌握python的语法,然后使用其来编写一些深度学习模型。比如说python中非常牛逼的numpy模块

    result = numpy.repeat(numpy.arange(data.__len__(),2)
    

    在这里,这个data对象,不光可以输入numpy本身的数组对象,其他数学模块的队列、数组都可以输入,这种特性在其他语言几乎不能想象。但如果我们滥用这种特性,就极有可能在一个庞大的项目中,因为一个函数导致行为失常。

    PS:针对python的类型检查,可以使用一个第三方库 enforce
    https://pypi.python.org/pypi/enforce

    4,矩阵乘积
    这几个月来,我隐隐感觉,在我们印象中无所不能的python,似乎也找到了自己想全面发力的领域——科学计算。而至于web应用,在我的学习过程中,我感觉似乎go语言更能胜任一些(原生的go协程可以很轻松地利用多线程处理访问web用户的各项请求)。
    现在python3可以使用 @ at符号,来进行矩阵乘积。就拿最简单线性拟合来说,f(x) = wx + b,如果这样表达,会让人产生误解。实际上这里的w不是一个参数,而是一个1Xn矩阵,而x也不是一个单独的变量,而是一个nX1矩阵。
    如果在python语言中写成w@x则更能让人理解。

    5,Print现在要以函数调用
    就是print(xxx),这怕是从python2向python3习惯迁移一来,最不习惯的。
    比如在python2中,我们常常这样使用

    try:
        notifier.loop(daemonize=True, callback=on_loop_func, pid_file='/tmp/pyinotify.pid', stdout='/tmp/pyinotify.log')
    except pyinotify.NotifierError, err:
        print >> sys.stderr, err
    

    这是pyinotify关于daemonize 循环的实例代码,通过这种方式,当运行出现错误时,可以将内容输出到sys.stderr中。然而到了python3,则一定要把print和一般函数一样对待。上面的功能应该这样去写

    print(err,file=sys.stderr)
    

    另外说下,python3的print还有其他用法,比如sep=参数,可以直接分隔输出内容

    6,更简洁的格式化
    python可以使用 % 符号或.format()方法来对字符串中的内容进行格式化。那么如果一个字符串中要格式化的内容很多呢?笔者就遇到写的脚本要创建类SQL语句,加上format的内容一行的内容变成了三行,非常不宜读。
    在python3.6中引入了f-strings,也就是格式化字符串,我这有官方的例子

    print(f'{batch:3} {epoch:3} / {total_epochs:3}  accuracy: {numpy.mean(accuracies):0.4f}±{numpy.std(accuracies):0.4f} time: {time / len(data_batch):3.2f}')
    

    可以看到,直接在字符串中包含了格式化的位数信息,甚至还添加了对象的处理方法(如numpy.mean)

    7,使用Unicode编码标准
    这个不用多说了,python2你写个脚本,如果有汉语注释,必须在头部加一行

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

    如果直接输入一些俄语啊、希伯来语的符号,也无法正常显示。而现在在python3中,这些问题都会得到比较好的解决。

    8,字典和**kwargs将会自动保存顺序(python3.6 or newer)
    这个不谈了,在处理数据流时挺重要的一个特性

    9,我暂时了解到,但没有充分实践的一些变化
    pickle模块压缩效率更高,速度更快
    更加优秀的super()函数

    10,并发编程的抽象化
    在python2中,我们使用threading创建多线程,通过multiprocessing来创建多进程。而在python3中,使用concurrent模块对这两者进行了抽象化,将并发任务抽象成模块中的futures对象。

    相关文章

      网友评论

        本文标题:从python2向python3迁移

        本文链接:https://www.haomeiwen.com/subject/ylolqftx.html