如何比较版本号--Python实现
需求
在写一个程序Django项目的setup程序(初始化环境,比如设置PIP源,安装该项目依赖的各种模块等操作)遇到一个系统当前模块版本和项目所需版本的比较然后给出建议是忽略还是升级。我的要求是不仅仅比较版本号是否一致以及返回最大版本号,而且还要给出建议是升级(当前系统包的版本号小于项目需要的版本号)还是忽略(当前系统包的版本号大于等于项目需要的版本号)。下图就是我们要去比较的东西。
解题分析
- 版本号虽然是数字组成但是一个整体的版本号无法通过数字进行比较需要拆解逐位比较
- 版本号有长度的区别我们可以称作位,比如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 -*- import sys def checkVersion(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
return CODE, 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 in range(amount):
expectedversionBITS.append("")
else:
amount = len(expectedversionBITS) - len(currentversionBITS)
for i in range(amount):
currentversionBITS.append("") """
逐位比较版本大小,为什么这里采用currentversionBITS的长度来循环呢,其实讲过上面的if语句后无论是currentversionBITS还是expectedversionBITS
位数都相同,这里采用那个长度来控制循环都可以。
"""
for i in range(len(currentversionBITS)):
try:
if int(currentversionBITS[i]) > int(expectedversionBITS[i]):
CODE = 88
MAX_VERSION = currentversion
return CODE, MAX_VERSION
elif int(currentversionBITS[i]) < int(expectedversionBITS[i]):
CODE = 99
MAX_VERSION = expectedversion
return CODE, MAX_VERSION
else:
CODE = 88
MAX_VERSION = expectedversion
except IndexError as err:
pass return CODE, MAX_VERSION def main():
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()
执行结果
算法二:不补位按最小长度循环
不补位就要安装最小位数长度循环,否则就会抛出异常,当然我们可以做异常处理,不过执行逻辑还是不要放在异常里因为异常会影响性能,再说明明这个异常可以避免干嘛还要让它出现呢。
#!/usr/bin/env python
# -*- coding: utf-8 -*- import sys def checkVersionG2(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 in enumerate(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)
except IndexError as err:
pass # 这里则用于找到当前的 MAX_VERSION 到底是currentversion还是expectedversion,只有找到了才能给出建议是忽略还是升级。
# 之前那种算法里没有,因为通过位数补全之后比较不存在一段数据不清状态。
if MAX_VERSION == currentversion:
CODE = 88
else:
CODE = 99 return CODE, MAX_VERSION def main():
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的实现,算法通用。这两个方法里面没有对版本号格式的检验简易增加,通过正则就可以。
如何比较版本号--Python实现的更多相关文章
- 【从0開始Tornado建站】0.9版本号python站点代码开源--持续更新中
从5月份開始[从0開始Tornado建站]这个专栏,開始一点一点把这个分类兴趣站点弄起来,从无到有的过程也是令人兴奋的:-) 国庆的时候等待备案然后上线,如今站点域名为ustchack ...
- linux查看python安装路径,版本号
一.想要查看ubuntu中安装的Python路径 方法一:whereis python 方法二:which python 二.想要查看ubuntu中安装的python版本号 python
- Redhat Linux下的python版本号升级
运行#Python与#python -V,看到版本是2.4.3,非常老了,并且之前写的都是跑在python3.X上面的,3.X和2.X有非常多不同, 有兴趣的朋友能够參考下这篇文章: http:// ...
- linux 查看python安装路径,版本号
一.想要查看ubuntu中安装的python路径 方法一:whereis python 方法二:which python 二.想要查看ubuntu中安装的python版本号 python ...
- Python 获得程序 exe 的版本号
Python 获得程序 exe 的版本号 python中需要安装 pywin32 包 # based on http://stackoverflow.com/questions/580924/pyth ...
- python grammar、C/C++ Python Parsing Engine
catalog . Python语言简介 . Python模块 . 嵌入式Python解析引擎: C++调用Python . Python 调用 C (base) . 扩展Python语法解析器功能: ...
- [Python 学习] 两、在Linux使用平台Python
在本节,它介绍了Linux如何使用平台Python 1. Python安装. 今天,大多数把自己的版本号Python的,它不能被安装.假设你要安装它,可以使用相应的安装指令. Fedora:先以roo ...
- python开发部署时新增数据库中表的方法
在项目版本让运维部署时,涉及到数据库表的增加问题,想了一下,可以有四种方法 1.使用SQLAlchemy的db.create_all()方法 # -*- coding:utf-8 -*- from f ...
- 腾讯云python网站开发环境搭建
前段时间腾讯云做活动,于是就花了几百大洋买了三年的云服务,准备在上 面安装python web的开发环境,下面将安装过程做一个总结,希望能够帮助大家. 一.使用环境 使用的软件环境为:CentOS ...
随机推荐
- RF无线射频电路设计干货分享
1.概述:射频(RF)PCB设计,在目前公开出版的理论上具有很多不确定性,常被形容为一种“黑色艺术”.通常情况下,对于微波以下频段的电路(包括低频和低频数字电路),在全面掌握各类设计原则前提下的仔细规 ...
- C#语言struct结构体适用场景和注意事项
在C#语言中struct结构体和class之间的区别主要是值类型和引用类型的区别,但实际上如果使用不当是非常要命的.从Win32时代过来的人对于struct一点不感觉陌生,但是却反而忽略了一些基本问题 ...
- VB6进行GZIP解压&C#进行GZIP压缩和解压
VB进行GZIP解压的,DLL是系统的,如果没有 [点击下载] Option Explicit 'GZIP API '----------------------------------------- ...
- MyBatis(十一) 嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则
(1)接口中编写方法 public Dept getDeptPlusById(Integer id); (2)Mapper文件 <resultMap type="com.eu.bean ...
- SharePoint Column Format
https://docs.microsoft.com/en-us/sharepoint/dev/declarative-customization/column-formatting . { &quo ...
- C#找不到ConfigurationManager类
c#添加了Configuration;后,竟然找不到 ConfigurationManager 这个类,后来才发现:虽然引用了using System.Configuration;这个包,但是还是不行 ...
- 【腾讯海纳】系统未发布时如何获取获取property_id在本地进行测试?
有现成https协议域名使用者,可忽略此文. 直接先上图,明白的人看一眼图片就知道怎么拿了,如下所示: 解释说明: 在完成添加套件,以及测试应用的前提下,按如下操作流程: 1.访问路径:登录“海纳开发 ...
- 201771010118 马昕璐《面向对象程序设计java》第十二周学习总结
第一部分:理论知识学习部分 用户界面:用户与计算机系统(各种程序)交互的接口 图形用户界面:以图形方式呈现的用户界面 AET:Java 的抽象窗口工具箱包含在java.awt包中,它提供了许多用来设计 ...
- RCNN论文细节
写在前面: 本系列笔记主要记录本人在阅读过程中的收获,尽量详细到实现层次,水平有限,欢迎留言指出问题~ 这篇文章被认为是深度学习应用于目标检测的开山之作,自然是要好好读一下的,由于文章是前些日子读的, ...
- js原型与继承
demofunction Fun(){} var foo = new Fun();foo.__proto__ === Fun.prototype 摘要 1.js本身不提供类实现,es6引入了class ...