Python之路--你不知道的platform
某次在查看测试机(Ubuntu)发行版本时,发现得到的结果并不准确;本应得到Ubuntu,结果显示的却是Debian,大致代码如下
...
distribution_name = ['centos', 'ubuntu', 'redhat', 'debian', 'fedora']
class_name = {'centos': 'CentOS',
'ubuntu': 'Ubuntu',
'redhat': 'RedHat',
'debian': 'Debian',
'fedora': 'Fedora'}
...
for name in distribution_name:
if name in platform.platform.lower():
_platform = class_name[name]
break
...
项目使用的是可移植版的python,第一反应是用交互模式验证一下。
>>> import platform
>>> platform.platform()
'Linux-4.4.0-62-generic-x86_64-with-debian-stretch-sid'
得出的结果确实为debian。既没有报错,也没有异常,那么问题是出在哪里了呢?
遂又使用系统自带的python验证。
>>> import platform
>>> platform.platform()
'Linux-4.4.0-62-generic-x86_64-with-Ubuntu-16.04-xenial'
然而系统得到的却是正确的结果,难道是移植版本的bug?
在同事的提醒下,意识到应该看一下platform模块的源码,看看问题是否出在这里。
首先,查看platform模块中的platform方法
def platform(aliased=0, terse=0):
result = _platform)_cache.get((aliased, terse), None)
if result is not None:
return resut
system, node, release, version, machine, processor = uname()
...
elif system in ('Linux', ):
disname, distversion, distid = dist('')
...
def uname():
...
try:
system, node, release, version, machine = os.uname()
...
def dist(distname='', version='', id='',
supported_dists=_supported_dists):
return linux_distribution(distname, version, id,
supported_dists=supported_dists,
full_distribution_name=0)
当调用platform方法时,首先它回去模块缓存信息中查找,若有则直接返回。因为是第一次调用,缓存中肯定不会存有相应信息,这里可以跳过。
接着,通过uname方法获取system, node, release等信息,而uname方法主要是调用os.uname()获得相应信息。
>>> import os
>>> os.uname()
('Linux', 'uyun-VirtualBox', '4.4.0-62-generic', '#83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017', 'x86_64')
尝试使用os.uname()后,除了能得到系统版本外发现并没有期望得到的相应发行版信息,跳过。
然后则是dist()方法。发现dist()方法实际上调用的python_implementation()。最终确定,获取系统版本的关键就在python_implementation()方法中。
以下为比较可移植版的python和Ubuntu自带的python源码(具体行号可能存在些许偏差)
...
259 _supported_dists = (
260 'SuSE', 'debian', 'fedora', 'redhat', 'centos',
261 'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
262 'UnitedLinux', 'turbolinux')
...
...
291 def linux_distribution(distname='', version='', id='',
292 supported_dists=_supported_dists,
293 full_distribution_name=1):
...
315 try:
316 etc = os.listdir('/etc')
317 except os.error:
318 # Probably not a Unix system
319 return distname, version, id
...
...
以上为移植版python的platform模块源码。
···
261 _supported_dists = (
262 'SuSE', 'debian', 'fedora', 'redhat', 'centos',
263 'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
264 'UnitedLinux', 'turbolinux', 'Ubuntu')
...
293 _distributor_id_file_re = re.compile("(?:DISTRIB_ID\s*=)\s*(.*)", re.I)
294 _release_file_re = re.compile("(?:DISTRIB_RELEASE\s*=)\s*(.*)", re.I)
295 _codename_file_re = re.compile("(?:DISTRIB_CODENAME\s*=)\s*(.*)", re.I)
296
297 def linux_distribution(distname='', version='', id='',
298 supported_dists=_supported_dists,
299 full_distribution_name=1):
...
321 # check for the LSB /etc/lsb-release file first, needed so
322 # that the distribution doesn't get identified as Debian.
323 try:
324 with open("/etc/lsb-release", "rU") as etclsbrel:
325 for line in etclsbrel:
326 m = _distributor_id_file_re.search(line)
327 if m:
328 _u_distname = m.group(1).strip()
329 m = _release_file_re.search(line)
330 if m:
331 _u_version = m.group(1).strip()
332 m = _codename_file_re.search(line)
333 if m:
334 _u_id = m.group(1).strip()
335 if _u_distname and _u_version:
336 return (_u_distname, _u_version, _u_id)
337 except (EnvironmentError, UnboundLocalError):
338 pass
339
340 try:
341 etc = os.listdir('/etc')
342 except os.error:
343 # Probably not a Unix system
344 return distname,version,id
...
...
以上为Ubuntu系统自带python的platform模块源码。
首先可以看到,Ubuntu版本中platform的_supported_dists 元组中多了一个Ubuntu元素,并且在linux_destribution方法中,首先会尝试读取/etc/lsb-release文件;接着通过正则匹配(_distributor_id_file_re, _release_file_re, _codename_file_re),查找相应的值,如果都有结果,则直接返回。
读取/etc/lsb-release,发现里面存了一些Ubuntu系统版本信息。
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
那么显然,三个正则都将匹配到对应的值,返回(Ubuntu, 16.04, xenial)。
最终,正确的获取到Ubuntu发行版本。
Python之路--你不知道的platform的更多相关文章
- Python之路,Day17 - 分分钟做个BBS论坛
Python之路,Day17 - 分分钟做个BBS论坛 本节内容: 项目:开发一个简单的BBS论坛 需求: 整体参考"抽屉新热榜" + "虎嗅网" 实现不同 ...
- Python之路,Day8 - Socket编程进阶
Python之路,Day8 - Socket编程进阶 本节内容: Socket语法及相关 SocketServer实现多并发 Socket语法及相关 socket概念 socket本质上就是在2台 ...
- Python之路【第一篇】python基础
一.python开发 1.开发: 1)高级语言:python .Java .PHP. C# Go ruby c++ ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...
- Python之路
Python学习之路 第一天 Python之路,Day1 - Python基础1介绍.基本语法.流程控制 第一天作业第二天 Python之路,Day2 - Pytho ...
- python之路 目录
目录 python python_基础总结1 python由来 字符编码 注释 pyc文件 python变量 导入模块 获取用户输入 流程控制if while python 基础2 编码转换 pych ...
- Python之路【第十九篇】:爬虫
Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...
- Python之路【第十八篇】:Web框架们
Python之路[第十八篇]:Web框架们 Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Pytho ...
- Python之路【第十七篇】:Django【进阶篇 】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路【第十六篇】:Django【基础篇】
Python之路[第十六篇]:Django[基础篇] Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...
随机推荐
- java系列-JDBC的封装
参考:http://blog.csdn.net/liuhenghui5201/article/details/16369773 一. 1.加载驱动-->>封装 --->> ...
- tomcat 安全文件夹(Java之负基础实战)
tomcat 解析网站的时候,会寻找一个文件叫 WEB-INF 这些文件外部无法访问
- C#中如何使用IComparable<T>与IComparer<T>接口(转载)
本分步指南描述如何使用两个接口: IComparer和IComparable.在同一篇文章中讨论这些接口有两个原因.经常在一起,使用这些接口和接口类似 (并且有相似的名称),尽管它们用于不同用途. 如 ...
- JS前端的分享功能
给网页加上分享代码,借助网友的力量推广网站,目前已经很流行了 以下是网页代码 QQ空间分享代码如下: <a href="javascript:void(0);" onclic ...
- 程序启动缓慢-原来是hbm.xml doctype的原因
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "h ...
- win7下安装sdks
原文及更多内容:http://yysource.sourceforge.net/?p=103 下载和安装 Windows 调试工具 http://msdn.microsoft.com/zh-CN/wi ...
- 我为什么不看好微信小程序
我自认为对新技术还是比较有热情的,可对于小程序这个“新技术”,我却完全是被动的.去年9月份的时候,微信小程序开始内测,瞬间引爆朋友圈.知乎等一众分享平台.当时我大概了解了一下,觉得从技术角度上来说没啥 ...
- 第二章:在HTML中使用JavaScript
1:在使用<script>嵌入JavaScript代码死,记住不要在代码中的任何地方出现"</script>"字符串 例如,浏览器在加载下面所示代码时就会产 ...
- WAS缓存导致的修改文件不生效问题【转】
WAS缓存导致的修改文件不生效问题: 解决方法: 一. 修改web.xml文件,需要修改以下三个目录下的文件: 1. /opt/IBM/WebSphere/AppServer/profiles/Dmg ...
- oracle_用户与概要文件
Oracle 用户与概要文件 2012-09-01 15:05:47| 分类: Oracle | 标签:用户与概要文件 |举报 |字号大中小 订阅 用户管理看上去简单其实也是最常出现问题的一个 ...