当前位置: 首页 > news >正文

Python 中最流行的十个标准库

作者 | Arghavan Moradi

译者 | Sambodhi

策划 | 刘燕

来源 | AI前线

Python 以其有用的库和包而著称,即使没有软件工程背景的人也能编程。本文基于 GitHub 仓库的示例数据集,探索流行的 Python 标准库。

Python 是当今人工智能和机器学习领域最流行的编程语言之一。Python 以其有用的库和包而著称,即使没有软件工程背景的人也能编程。

Python 拥有一组与 Python 语言一起分发的标准库,如 DateTime、math 或 Random。本文的目标是在 GitHub 的 Python 仓库中找到 10 个最有用的标准库。为实现我们的目标,我们研究了 GitHub 中不同的 Python 仓库,并收集了它们的旧库来回答这个问题。

为了开始我们的研究,首先,我们收集了 GitHub 中 5 个著名的 Python 资源库在过去一年的提交情况。然后,我们对这些仓库中的 Python 源文件进行解析,并收集其提交中使用的库。最后,我们将这些 GitHub 仓库提交中使用的 10 个最流行的 Python 标准库进行可视化。

如何收集数据?

有不同的方法可以访问 GitHub 仓库中的数据,例如 GitHub torrent、Git API 调用或 Google big query。但是,在本文中,我们想要尝试一个新的非常有用的 Python 包,名为 Pydriller,它可以收集我们需要的数据。Pydriller 速度快,使用方便。我是在攻读博士学位的时候熟悉了这个有趣的包。你可以在 这里 查看 Pydriller 的文档。要从 Pydriller 开始,首先,我们安装包:

pip install pydriller

每次提交时,GitHub 中的一个或多个源文件都可以被修改。在 GitHub 这样的版本控制系统中,每一次提交都有一个文件,名为“diff”。它通过提交特定的提交来存储在源文件中应用的更改。在 GitHub 仓库的提交中查找库的方法之一是在“diff”文件中搜索正则表达式。

但在本文中,我们想尝试一些不同的方法。我们比较两个不同版本的源文件“提交之前”和“提交之后”应用提交,然后收集这两个文件在库名中的差异。

通过这种方法,我们就可以发现库在不同提交中的使用频率。好消息是,Pydriller 允许我们在应用提交之前和应用提交之后访问源文件的版本。下面是收集数据所需的代码:

#import libraries
import pydriller as pyd
from datetime import datetime
#period to collect data
dt1 = datetime(2019, 11, 1)
dt2 = datetime(2020, 11, 1)
#path of 5 Python repositories
path = ["https://github.com/django/django.git","https://github.com/pandas-dev/pandas.git",
        "https://github.com/numpy/numpy","https://github.com/home-assistant/home-assistant.git",
        "https://github.com/donnemartin/system-design-primer.git"]
#collecting a version of a source file before and after applying a commit
tf_source = pd.DataFrame(columns=['commit_ID', 'before_Commit', 'after_Commit'])
for commit in pyd.RepositoryMining(path_to_repo=path, since=dt1, to=dt2).traverse_commits():
    for modified_file in commit.modifications:
        if modified_file.filename.endswith(".py"):
            tf_source = tf_source.append({'commit_ID': commit.hash,'before_Commit': modified_file.source_code_before,
                                          'after_Commit': modified_file.source_code}, ignore_index=True)

用 Pydriller 在 GitHub 中收集 5 个著名的 Python 库。

我们在 GitHub 上收集了 5 个大的 Python 项目在去年的提交情况,其中有 Django、Pandas、NumPy、Homeassistant、system-design-primer。“RepositoryMining”是 Pydriller 的主要 API 调用之一。

我们可以通过 RepositoryMining 中的两个参数来定义一个时间段来收集不同仓库中的提交:sinceto。另外,我们考虑所有名称以“.py”结尾的源文件的提交,因为这些资源库中也有其他编程语言的源文件,但我们关注的是 Python 库。

我们收集了三个特征:commit.hashsource_code_beforesource_code。Pydriller 中的commit.hash返回提交的idsource_code_before是应用提交前的源文件版本,source_code则显示提交后的源文件内容。下面是我们收集的数据头:

tf_source.head()

到目前为止,我们已经收集了开始旅程所需的数据。在下一节中,我们将学习如何探索这些源文件中的库。

如何解析 Python 源代码

提取源代码中信息的方法之一是将它们转换成抽象语法树(Abstract Syntax Tree,AST)。然后,我们就可以遍历这棵树,并收集目标节点。

但最重要的一点是,我们只想收集 Python 标准库,而不是所有在仓库中使用的包,比如本地定义的库,它们只有在仓库中才有意义。Python 标准库是和 Python 语言一起发布的。

因此,为了将标准包和其他包分开,我们需要拉取 Python 中所有有效的标准库。然后,我们可以写一个函数来收集源代码中的库名。

我们可以将本节分为两步:收集 Python 中所有可用的标准库的列表、构建基于抽象语法书的函数来收集库名。

1. 收集 Python 中所有可用的标准库的列表

在 Python 的网站 上,有一张 Python 中所有标准库的列表,并附有简短说明。这个页面将所有的 Python 标准库按字母名称排序,帮助我们对 Python 中所有的标准库进行拉取。我把所有 Python 标准库的列表放在 这里,以 .csv 的格式。

2. 构建基于抽象语法书的函数来收集库名

既然我们有了所有标准 Python 库的列表,我们就需要从 Python GitHub 仓库中收集我们示例数据集中的库名称。正如我们提到的,其中一种方法是遍历抽象语法树。

在本文中,我们的目标节点是importimportfrom。我们希望有一个函数遍历解析树,找到目标节点,并返回库的名称。下面是这样做的类。

#import libraries
import ast
import tokenize
#A class to walk trough AST and collect libraries name
class FuncParser(ast.NodeVisitor):
def visit_Import(self, node):
tempImpo = node.names
if(tempImpo != None):
listImpo = tempImpo[0]
Impo = listImpo.name
if (Impo in api_name):
file_contents.append(Impo)
ast.NodeVisitor.generic_visit(self, node)
else:
ast.NodeVisitor.generic_visit(self, node)
def visit_ImportFrom(self, node):
module=node.module
if(module in api_name):
file_contents.append(module)
else:
ast.NodeVisitor.generic_visit(self, node)
def generic_visit(self, node):
ast.NodeVisitor.generic_visit(self, node)

在 Python 代码中收集库名的类。

为了更好地理解这个类的工作原理,下面是一段简单的代码。这段示例代码只有两行,分别导入了两个不同的库,其中一个是 python 标准库:tokenize,另一个是本地库:assistant

import tokenize as tz
import assistant as ass

下面是这个示例代码的解析树的转储。可以发现,我们需要收集的是作为alias类中的name参数。

此外,我们还需要检查库的名称是否在我们从 Python 原始网站收集的所有标准库的列表中。我们将 .csv 文件保存在名为api_name的列表中。

如果我们在这个示例代码上应用这个类FuncParser,它将只返回tokenize,因为另一个库assistant在 Python 标准库列表中不可用。

Module(body=[Import(names=[alias(name='tokenize', asname='tz')]), Import(names=[alias(name='assistant', asname='ass')])])

Python 仓库中基于 GitHub 提交的 10 个最流行标准库是什么

到目前为止,我们收集了 GitHub 中 5 个著名的 Python 仓库的示例数据集,并构建了一个类来收集 Python 代码中的库名。

现在,我们需要将这个函数应用到 GitHub 的示例数据中,并找出这些仓库的提交中使用的前 10 个库。正如我们前面所讨论的,我们将提交提交之前的源文件的抽象语法树和提交提交之后的同一源文件的抽象语法树进行比较,然后我们收集不同的库节点。

然后我们收集不同的库节点。首先,我会给大家展示一个步骤性的示例,告诉大家如何比较这两个抽象语法树,最后,我把所有的代码放在一起,以循环遍历整个数据集,并计算每个库的出现次数。

1. 提交提交之前收集库名列表

我们将示例数据集存储在tf_source中,我选择这个数据集的第一行来解释整个过程。tf_source'Commit_before' 返回示例数据集中第一次提交前的代码内容。

然后,我们应用FuncParser()来收集这个源文件中的所有库名,并在file_contents列表中返回结果。我们创建一个名为tokens_before的数据框架,并存储这个列表。

text_before=str(tf_source[‘Commit_before’](0))

bf_obj = FuncParser()
bf_tree = ast.parse(text_before)
file_contents = []
bf_obj.visit(bf_tree)
dtobj_before = pd.DataFrame(file_contents, columns=[‘token’])
tokens_before =pd.DataFrame(dtobj_before[‘token’].value_counts())

2. 提交提交之后收集库名列表

我们重复与上面的步骤相同的过程,但这次是在提交提交之后对源文件的内容进行的,tf_source‘Commit_after’。

另外,我们将结果存储在一个名为tokens_after的数据帧中。

text_after=str(tf_source[‘Commit_after’](0))

 aft_obj = FuncParser()
aft_tree = ast.parse(text_after)
file_contents = []
aft_obj.visit(aft_tree)
dtobj_after = pd.DataFrame(file_contents, columns=[‘token’])
tokens_after =pd.DataFrame(dtobj_after[‘token’].value_counts())

3. 找出这两个列表之间的差异

在这一步中,我们从tokens_after中减去tokens_before以计算它们的差异。

diff = tokens_after.subtract(tokens_before)
diff_token = diff[(diff.select_dtypes(include=[‘number’]) != 0).any(1)]
diff_token=diff_token.fillna(0)
diff_token= diff_token.abs()
diff_token = diff_token.reset_index()

4. 计算库的数量

最后,我们统计每个库在diff_token数据帧中出现的次数。为此,我们创建一个名为py_lib的字典,并统计库的出现次数。

py_lib={}
j=0
for j in range(0,len(diff_token)):
word = diff_token['index'](j).lower()
if word in py_lib:
py_lib[word]+=diff_token['token'](j)
else:
py_lib[word]=1
j+=

为了将上述步骤应用于我们在前面收集的整个示例数据中,我在步骤的开头添加了一个循环。下面是代码:

i=0
error=0
py_lib={}
for row in tf_source.iterrows():

#parsing the source file before applying commit i
if tf_source['Commit_before'](i) is not None:
try:
text_before=str(tf_source['Commit_before'](i))


bf_obj = FuncParser()
bf_tree = ast.parse(text_before)
file_contents = []
bf_obj.visit(bf_tree)
dtobj_before = pd.DataFrame(file_contents, columns=['token'])
tokens_before =pd.DataFrame(dtobj_before['token'].value_counts())

except:
error +=1
else:
file_contents = []
dtobj_before = pd.DataFrame(file_contents, columns=['token'])
tokens_before =pd.DataFrame(dtobj_before['token'].value_counts())

#parsing the source file after applying commit i
if tf_source['Commit_after'](i) is not None:
try:
text_after=str(tf_source['Commit_after'](i))


aft_obj = FuncParser()
aft_tree = ast.parse(text_after)
file_contents = []
aft_obj.visit(aft_tree)
dtobj_after = pd.DataFrame(file_contents, columns=['token'])
tokens_after =pd.DataFrame(dtobj_after['token'].value_counts())

except:
error +=1
else:
file_contents = []
dtobj_after = pd.DataFrame(file_contents, columns=['token'])
tokens_after =pd.DataFrame(dtobj_after['token'].value_counts())


#calculating the differences between two list tokens_before and tokens_after
diff = tokens_after.subtract(tokens_before)
diff_token = diff[(diff.select_dtypes(include=['number']) != 0).any(1)]
diff_token=diff_token.fillna(0)
diff_token= diff_token.abs()
diff_token = diff_token.reset_index()

# counting the numer of each libraries which are added or removed by commit i
j=0
for j in range(0,len(diff_token)):
word = diff_token['index'](j).lower()
if word in py_lib:
py_lib[word]+=diff_token['token'](j)
else:
py_lib[word]=1
j+=1

i+=1

在整个示例数据集中收集库。

现在我们收集了 GitHub 中所有 Python 仓库的库及其提交频率,我们想在py_lib字典中找到前 10 个库。我们可以用下面的代码将前 10 个库的值收集到一个字典中。

我们可以看到,从示例数据集来看,warningssysdatetime等库都在 Python 标准库的前 10 名列表中。

from operator import itemgetter
d=sorted(py_lib.items(), key=itemgetter(1),reverse=True)[:10]
[('warnings', 96.0),
('sys', 73.0),
('datetime', 28.0),
('test', 27.0),
('os', 22.0),
('collections', 18.0),
('io', 16.0),
('gc', 10.0),
('functools', 9.0),
('threading', 7.0)]

基于 GitHub 示例数据集的 Python 十大标准库。

另外,我们还可以绘制 Python 库的词云图及其频率。

import matplotlib.pyplot as plt
from wordcloud import WordCloud
wordcloud = WordCloud(background_color='black',max_font_size = 50)
wordcloud.generate_from_frequencies(frequencies=py_lib)
plt.figure(figsize=(8,6))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()

基于 GitHub 示例数据集的流行 Python 库的词云图。

总  结

在本文中,我们尝试基于一个示例数据集收集 10 个最受欢迎的 Python 库。这个数据集包含了 GitHub 中 5 个著名的 Python 仓库最近一年的提交情况。

我们使用 Pydriller 来收集 GitHub 的数据。我们对提交之前和提交之后的源文件抽象语法树进行了比较,并收集了这些提交中使用的库列表。最后,我们在词云图中绘制了最流行的 Python 库。

作者介绍:Arghavan Moradi,博士研究生,热爱学习,喜欢分享。

推荐阅读 

《Python 3标准库》全书以案例驱动的方式讲解了标准库中数百个模块的使用方法和工作原理,比标准库的官方文档更容易理解,为Python程序员熟练掌握和使用这些模块提供了绝佳指导。是所有Python程序员都必备的工具书!

更多精彩回顾

书讯 | 1月书讯:Hello 2021! (上)

书讯 | 1月书讯:Hello 2021! (下)

资讯 | TIOBE 1 月编程语言:Python 摘得 2020 年度编程语言!

书单 | 8本书助你了解人民日报“创作大脑”

干货 | 曾被“劝退”的 C++ 20 正式发布!

收藏 | DB-Engines:PostgreSQL获得“2020年度数据库”荣誉

上新 | ECharts开山之作,官方推荐!精心规划适合初学者的ECharts学习路径!

赠书 | 【第38期】移动边缘计算MEC,站在5G“中央”

点击阅读全文购买

相关文章:

  • IDC发布2021年中国人工智能市场10大预测
  • “绿宝书”好在哪?前端大佬们都在推荐
  • 【第39期】打破“打工人”魔咒,RPA 来狙击!
  • 适合的才是最好的,小众数据库黑马不可小觑
  • 刚刚拿下「中国AI最高奖」的语音技术,能给我们带来什么?
  • 百度官方文档Plus版,PaddlePaddle深度学习框架介绍
  • 华为首席开源联络官执笔,带你了解5G时代的边缘计算
  • 寒假到了,神兽归笼?程序员整治“熊孩子”有妙招
  • 读完《Effective Java》后,我总结了 50 条开发技巧
  • 手把手教你如何制作可视化大屏!
  • 使用 SQL 语句实现一个年会抽奖程序
  • 构建全球第三大移动生态,2021年,华为HMS生态要起飞了!
  • 2020年云原生技术关键趋势总结
  • 【第40期】不可错过的数据挖掘好书
  • 6个关键步骤,手把手教你构建图模型
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • CSS 提示工具(Tooltip)
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • Hibernate最全面试题
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • JavaScript设计模式与开发实践系列之策略模式
  • Mysql优化
  • npx命令介绍
  • NSTimer学习笔记
  • SQLServer之创建显式事务
  • 分类模型——Logistics Regression
  • 解析带emoji和链接的聊天系统消息
  • 前端临床手札——文件上传
  • 使用权重正则化较少模型过拟合
  • 我建了一个叫Hello World的项目
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​决定德拉瓦州地区版图的关键历史事件
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • ${ }的特别功能
  • (26)4.7 字符函数和字符串函数
  • (C#)获取字符编码的类
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (排序详解之 堆排序)
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (十一)手动添加用户和文件的特殊权限
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)http协议
  • (转)nsfocus-绿盟科技笔试题目
  • *2 echo、printf、mkdir命令的应用
  • ./configure,make,make install的作用
  • .gitignore文件_Git:.gitignore
  • .NET 命令行参数包含应用程序路径吗?
  • .NetCore项目nginx发布
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • [20171113]修改表结构删除列相关问题4.txt
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [Android] Upload package to device fails #2720