oneliner: 扫描python 仓库 import 信息

举报
oneliner 发表于 2020/04/03 01:25:54 2020/04/03
【摘要】 在python 裸仓库下扫描并格式化import语句, 生成包列表

收集整个仓库的import信息

前置管道逻辑是: find 命令寻找所有 *.py 文件 | 用 grep -v 过滤包含EXCLUDE 的文件 | 对每个文件, 提取包含 import 的行 | 删除行首的 leading whitespace

 find ./ -name "*.py" |grep -v EXCLUDE | xargs grep -h "import" | sed 's/[ \t]*//' > imports

 到这一步, 输出是这样:


1585842175889121.png

接下来针对不同的import 语句提取包的名字。

提取package 列表

针对不同的 python 的导入语句处理上一步的结果, 得到完整的包列表。

整包导入:import xx,yy 

  导入1个包:  import package1

  导入N个包: import package1, package2, package3

  

cat imports |egrep "^import" | sed 's/import[ \t]\+//' |awk -F"," '{for(i=1;i<=NF;i++)print $i}' |sed 's/^[ \t]\+//' | awk  '{print $1}' | awk -F"." '{print $1}'  |sort -u

    行首匹配 import | 移除 import 及后面的whitespace | 一次导入N个包则每个包输出一行,如果只有1个包则原样输出 | 删除输出造成的leading white space  | 如果有 import A as B 仅输出 A |  如果有 import A.B 仅输出 A |  排序去重


看起来是这样

1585848233108603.png

部分导入:from A.B import xx, yy

  选择部分导入: from package.x  import A,B,C

cat imports| egrep "^from" | sed 's/from[ \t]\+//'  | awk  '{print $1}' | awk -F"." '{print $1}'  |sort -u

  行首匹配 from | 移除 from 及后面的whitespace | 拿到包的名字 |  如果有  A.B 仅输出 A |  排序去重


看起来是这样:

1585847511268393.png


总结

  1.   运行速度非常快,秒级

  2.   awk -F"," '{print $1}' 的默认行为很有意思,如果该行不包含  "," , 会把整行输出, 这个默认行为让代码简单了很多

  3.   不能处理跨行的 import。 多数情况下不是问题, 比如我做这个需求是为了收集信息写 requirements.txt , 如果个别遗漏,执行冒烟报错, 少量修改即可添加完整。

  4.   管道中很多逻辑是处理white spaces 的,看起来很罗嗦但是对异常覆盖的很好, 原因不多说

  5. 有没有现成的轮子? 有! 但是都假设你在某个特定的 virtualenv 下, pip 或者 conda 会维护当前虚拟环境的包信息

    1. pip3 freeze > requirements.txt

    2. conda list -e > requirements.txt

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。