如何比较版本号--Python实现

摘要:
/usr/bin/envpython#-*-coding:utf-8-*-importsysdefcheckVersion:"""检查版本号是否相同,当前版本小于期望版本则进行升级,大于等于则忽略。:paramcurrentversion:当前系统存在的版本号:paramexpectedversion:期望的版本号:return:CODE,MAX_VERSION"""MAX_VERSION="0.0.0"CODE=88#如果两者一样就直接返回,用于加快处理速度。ifexpectedversion==currentversion:CODE=88MAX_VERSION=expectedversionreturnCODE,MAX_VERSION#切割成列表currentversionBITS=currentversion.split(".")expectedversionBITS=expectedversion.split(".")"""为了避免版本号长度不同比如1.0.8和1.2我们把版本号要补全都变成相同长度,比如1.2.0这样比较的时候循环次数相同"""iflen˃=len:amount=len-lenforiinrange:expectedversionBITS.append("0")else:amount=len-lenforiinrange:currentversionBITS.append("0")"""逐位比较版本大小,为什么这里采用currentversionBITS的长度来循环呢,其实讲过上面的if语句后无论是currentversionBITS还是expectedversionBITS位数都相同,这里采用那个长度来控制循环都可以。
需求

在写一个程序Django项目的setup程序(初始化环境,比如设置PIP源,安装该项目依赖的各种模块等操作)遇到一个系统当前模块版本和项目所需版本的比较然后给出建议是忽略还是升级。我的要求是不仅仅比较版本号是否一致以及返回最大版本号,而且还要给出建议是升级(当前系统包的版本号小于项目需要的版本号)还是忽略(当前系统包的版本号大于等于项目需要的版本号)。下图就是我们要去比较的东西。

如何比较版本号--Python实现第1张

解题分析

  • 版本号虽然是数字组成但是一个整体的版本号无法通过数字进行比较需要拆解逐位比较
  • 版本号有长度的区别我们可以称作位,比如1.1.1这就是3位,我们这里的位说的是“.”分割的位数。 1.111.1也是三位。位数就是“.”的个数加1.

算法一:补位算法

比如1.11.2和1.9比较,既然是逐位比较那就需要循环,两个版本号位数不同如果按照最长的位数循环那短的哪一个肯定抛异常,那么我就可以通过补位来实现,怎么补呢?1.9 和 1.9.0 看到了么,这两个版本号是相同的,为什么呢?有谁见过1位的版本号呢?都使用1.0而不会单纯使用1,长度相同那剩下的就是循环比较。

#!/usr/bin/env python
#-*- coding: utf-8 -*-
importsys
defcheckVersion(currentversion, expectedversion):
    """
    检查版本号是否相同,当前版本小于期望版本则进行升级,大于等于则忽略。
    CODE有两种,88和99 表示建议,88表示当前版本大于等于期待的版本忽略,99表示小于期待版本要进行升级。
    :param currentversion: 当前系统存在的版本号
    :param expectedversion: 期望的版本号
    :return: CODE, MAX_VERSION
    """
    MAX_VERSION = "0.0.0"
    CODE = 88
    #如果两者一样就直接返回,用于加快处理速度。 这里不要用 is 要用 == 来比较内容是否一致。
    if expectedversion ==currentversion:
        CODE = 88
        MAX_VERSION =expectedversion
        returnCODE, MAX_VERSION
    #切割成列表
    currentversionBITS = currentversion.split(".")
    expectedversionBITS = expectedversion.split(".")
    """
    为了避免版本号长度不同比如  1.0.8和1.2 我们把版本号要补全都变成相同长度,比如 1.2.0 这样比较的时候循环次数相同
    """
    if len(currentversionBITS) >=len(expectedversionBITS):
        amount = len(currentversionBITS) -len(expectedversionBITS)
        for i inrange(amount):
            expectedversionBITS.append("0")
    else:
        amount = len(expectedversionBITS) -len(currentversionBITS)
        for i inrange(amount):
            currentversionBITS.append("0")
    """
    逐位比较版本大小,为什么这里采用currentversionBITS的长度来循环呢,其实讲过上面的if语句后无论是currentversionBITS还是expectedversionBITS
    位数都相同,这里采用那个长度来控制循环都可以。
    """
    for i inrange(len(currentversionBITS)):
        try:
            if int(currentversionBITS[i]) >int(expectedversionBITS[i]):
                CODE = 88
                MAX_VERSION =currentversion
                returnCODE, MAX_VERSION
            elif int(currentversionBITS[i]) <int(expectedversionBITS[i]):
                CODE = 99
                MAX_VERSION =expectedversion
                returnCODE, MAX_VERSION
            else:
                CODE = 88
                MAX_VERSION =expectedversion
        exceptIndexError as err:
            pass
    returnCODE, MAX_VERSION
defmain():
    print checkVersion("1.0", "1.1")  #正确的返回 99 1.1
    print checkVersion("1.1.2", "1.1")  #正确的返回 88 1.1.2
    print checkVersion("1.11.3", "1.11.24")  #正确的返回 99 1.11.24
    print checkVersion("1.0.11.3", "1.0.11.2")  #正确的返回 88 1.0.11.3
if __name__ == "__main__":
    try:
        main()
    finally:
        sys.exit()

执行结果

如何比较版本号--Python实现第2张

算法二:不补位按最小长度循环

不补位就要安装最小位数长度循环,否则就会抛出异常,当然我们可以做异常处理,不过执行逻辑还是不要放在异常里因为异常会影响性能,再说明明这个异常可以避免干嘛还要让它出现呢。

#!/usr/bin/env python
#-*- coding: utf-8 -*-
importsys
defcheckVersionG2(currentversion, expectedversion):
    """
    检查版本号是否相同,当前版本小于期望版本则进行升级,大于等于则忽略.本方法是基于第一种方法的改进,性能更好,代码更少。
    CODE有两种,88和99 表示建议,88表示当前版本大于等于期待的版本忽略,99表示小于期待版本要进行升级。
    :param currentversion: 当前系统存在的版本号
    :param expectedversion: 期望的版本号
    :return: CODE, MAX_VERSION
    """
    MAX_VERSION = "0.0.0"
    #切割成列表
    currentversionBITS = currentversion.split(".")
    expectedversionBITS = expectedversion.split(".")
    """
    找出2个版本号位数最小的一个,注意这里就存在数据互换问题,经过这个if语句之后,你就完全不知道 minbitversion和maxbitversion
    分别对应的是currentversion还是expectedversion.
    """
    if len(currentversionBITS) >=len(expectedversionBITS):
        minbitversion =expectedversionBITS
        maxbitversion =currentversionBITS
    else:
        minbitversion =currentversionBITS
        maxbitversion =expectedversionBITS
    """
    逐位比较版本大小,按最小位循环,这个循环之后将会找出版本号最大的,而且这里必须让这个循环完成。这里和之前的算法不同。
    再多说一句,这里你也可以按照最大位循环,但是你就需要考虑异常,从程序性能角度来说尽量不要使用异常控制逻辑,除非没有更好的选择。
    """
    for index, bit inenumerate(minbitversion):
        try:
            if int(bit) >int(maxbitversion[index]):
                MAX_VERSION = ".".join(minbitversion)
                break
            elif int(bit) <int(maxbitversion[index]):
                MAX_VERSION = ".".join(maxbitversion)
                break
            else:
                MAX_VERSION = ".".join(maxbitversion)
        exceptIndexError as err:
            pass
    #这里则用于找到当前的 MAX_VERSION 到底是currentversion还是expectedversion,只有找到了才能给出建议是忽略还是升级。
    #之前那种算法里没有,因为通过位数补全之后比较不存在一段数据不清状态。
    if MAX_VERSION ==currentversion:
        CODE = 88
    else:
        CODE = 99
    returnCODE, MAX_VERSION
defmain():
    print checkVersionG2("1.0", "1.1")  #正确的返回 99 1.1
    print checkVersionG2("1.1.2", "1.1")  #正确的返回 88 1.1.2
    print checkVersionG2("1.11.3", "1.11.24")  #正确的返回 99 1.11.24
    print checkVersionG2("1.0.11.3", "1.0.11.2")  #正确的返回 88 1.0.11.3
if __name__ == "__main__":
    try:
        main()
    finally:
        sys.exit()

执行结果

如何比较版本号--Python实现第3张

总结

上面只是用了Python的实现,算法通用。这两个方法里面没有对版本号格式的检验简易增加,通过正则就可以。

免责声明:文章转载自《如何比较版本号--Python实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇触发器不能读它的问题Activity并行网关和排他网关下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Windows平台Python编程必会模块之pywin32

在Windows平台上,从原来使用C/C++编写原生EXE程序,到使用Python编写一些常用脚本程序,成熟的模块的使用使得编程效率大大提高了。 不过,python模块虽多,也不可能满足开发者的所有需求。而且,模块为了便于使用,通常都封装过度,有些功能无法灵活使用,必须直接调用Windows API来实现。 要完成这一目标,有两种办法,一种是使用C编写Py...

进程基础知识 操作系统 操作系统的发展史(多道技术) 进程介绍 python并发编程之:多进程

day31一丶进程基础知识 什么是程序: 程序就是一堆文件 什么是进程: 进程就是一个正在执行的文件/程序,是对各种资源管理的集合, 进程不具有执行的能力 每个应用是以一个整体的形式暴露给操作系统去管理,里面包含对各种资源的调用,内存的管理,网络接口的调用等等 进程被谁执行: CPU最终运行你的程序,操作系统调用作用,将磁盘上的程序读取到内存中,然后交由...

python版本更新升级后第三方库不见了的问题

1、像卸载一般电脑程序一样,把老的Python 3.6.2版本卸载,会自动删除之前配置的环境变量信息 2、官网下载最新的python版本,安装的时候记得勾选Add Python 3.9.5 to PATH就行,会自动添加环境变量 3、pycharm解释器也需要更新下设置,否则执行程序就会报下面的粉红色背景的错误: Error running 'login'...

python打包

python打包 python打包 python打包有一个组织叫python packaging authority(pypa).还有一个python第三方仓库叫Python Package Index(Pypi) 与包有关的两种工具,一种是安装包的工具,另一种工具用于包的创建和分发 安装包的工具 pip安装来自PyPI的包 virtualenv或v...

Python-判断正负小数

#1、必须只有一个小数点 #2、小数点的左边必须是整数,小数点的右边必须是正整数 def is_float1(s=None): s = str(s) #.1 if s.count('.')==1: left,right = s.split('.') #['-','1'] if left.isdigit() a...

Python map 函数 -Python零基础入门教程

目录 一.前言 二.Python map 函数语法简介 三.Python map 函数实战 1.使用 map 函数 2.map 函数配合 lambda 匿名函数一起使用 四.Python map 函数效率对比 五.Python map 函数总结 六.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Pyt...