pip-pop源码阅读笔记
来源:互联网 发布:淘宝客服一般几点下班 编辑:程序博客网 时间:2024/06/05 14:44
项目地址:kennethreitz/pip-pop
git clone https://github.com/kennethreitz/pip-pop.git
下载下来后的目录结构是这样的
|+---bin| pip-diff| pip-grep|LICENSE (就是项目遵守的协议,看了下是MIT协议。|README.rst (相当于README.md|requirements.txt (依赖包|setup.py (安装脚本
看到bin目录下的py脚本没有后缀,我当时有点疑惑,但是看到了Shebang,恍然大悟了。。
#!/usr/bin/env python
也许这个项目本身就不是为windows用户提供使用的
README.rst是个啥
平时逛github找东西的时候,发现大多数都是README.md。突然出来一个README.rst,顿时手足无措啊。这个文件介绍了如何使用pip-pop库,以及这个项目未来要做的事情。
找了下资料才知道,rst是reStructuredText的缩写,马上就懂了。想起md是Markdown啊,PyPI不支持Markdown格式,所以才用的reStructuredText。都是标记语言,而且都比HTML好啊。为了证实我的想法,我在PyPI上搜索这个库,结果真的存在!
PyPI地址:pip-pop
依赖的库
requirements.txt里的内容是
docopt==0.6.2wsgiref==0.1.2
这两个库,只有wsgiref我有点印象,还记得Python2.7中那个非常给力的小工具吗?
python -m SimpleHTTPServer
对于docopt之前我是没有任何接触的。简单的说wsgiref就是个创建WSGI应用的工具,docopt是个命令行参数解析库/命令行界面构建工具。重点不在这两个依赖库,读懂项目的源码才是我要做的事情。
setup.py
"""pip-pop manages your requirements files. """import sys #获取命令行参数使用的from setuptools import setup #easy_install安装第三方包时就是调用setuptools来进行安装的setup( name='pip-pop', #库名 version='0.1.0', #版本 url='https://github.com/kennethreitz/pip-pop', #项目地址 license='MIT', #协议 author='Kenneth Reitz', #作者 author_email='me@kennethreitz.org', #邮箱 description=__doc__.strip('\n'), #packages=[], scripts=['bin/pip-diff', 'bin/pip-grep'], #项目包含的脚本 #include_package_data=True, zip_safe=False, platforms='any', #咦,居然是任何平台,但是写了shabang又在windows上用,真的友好吗? install_requires=['docopt'], #这个项目必须安装的依赖 classifiers=[ #元信息 # As from https://pypi.python.org/pypi?%3Aaction=list_classifiers #'Development Status :: 1 - Planning', #'Development Status :: 2 - Pre-Alpha', #'Development Status :: 3 - Alpha', 'Development Status :: 4 - Beta', #'Development Status :: 5 - Production/Stable', #'Development Status :: 6 - Mature', #'Development Status :: 7 - Inactive', 'Programming Language :: Python', 'Programming Language :: Python :: 2', #'Programming Language :: Python :: 2.3', #'Programming Language :: Python :: 2.4', #'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', #'Programming Language :: Python :: 3', #'Programming Language :: Python :: 3.0', #'Programming Language :: Python :: 3.1', #'Programming Language :: Python :: 3.2', #'Programming Language :: Python :: 3.3', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Topic :: System :: Systems Administration', ])
pip-diff
#!/usr/bin/env python# -*- coding: utf-8 -*-#在项目中常见的DocStrings,这里用于生成命令行界面,平时。。。用到的地方好像是多行字符串来着#<>位置参数,[]可选参数,()必选参数,|分隔两个互斥参数。…用于表示格式为数组的参数"""Usage: pip-diff (--fresh | --stale) <reqfile1> <reqfile2> [--exclude <package>...] pip-diff (-h | --help)Options: -h --help Show this screen. --fresh List newly added packages. --stale List removed packages.""" import osfrom docopt import docopt #生成命令行界面from pip.req import parse_requirements # = = 下面直接说用法就好了,说不清这个from pip.index import PackageFinder #PackageFinder是一个类from pip._vendor.requests import session #蛋疼,是个空的。。。requests = session() #生成一个会话,管理上下文class Requirements(object): #新类式 def __init__(self, reqfile=None): super(Requirements, self).__init__() #很坑爹的super类 self.path = reqfile self.requirements = [] if reqfile: #reqfile不是空的,就load这个文件 self.load(reqfile) def __repr__(self): #内置函数 x.__repr__() <==> repr(x),生成字符串,这里是重载了 return '<Requirements \'{}\'>'.format(self.path) #返回<Requirements '路径'> def load(self, reqfile): if not os.path.exists(reqfile): #文件不存在,抛出异常,停止执行 raise ValueError('The given requirements file does not exist.') finder = PackageFinder([], [], session=requests) #寻找包的,,,看源码神坑 for requirement in parse_requirements(reqfile, finder=finder, session=requests): if requirement.req: if not getattr(requirement.req, 'name', None): #不存在requirement.req.name # Prior to pip 8.1.2 the attribute `name` did not exist. requirement.req.name = requirement.req.project_name self.requirements.append(requirement.req) def diff(self, requirements, ignore_versions=False, excludes=None): r1 = self r2 = requirements results = {'fresh': [], 'stale': []} # Generate fresh packages. #坑爹的列表推导的if-else inline,然后组成元组,看到这里我炸了。。。学习了 other_reqs = ( [r.name for r in r1.requirements] if ignore_versions else r1.requirements ) for req in r2.requirements: r = req.name if ignore_versions else req #python 三元表达式 if r not in other_reqs and r not in excludes: results['fresh'].append(req) # Generate stale packages. other_reqs = ( [r.name for r in r2.requirements] if ignore_versions else r2.requirements ) for req in r1.requirements: r = req.name if ignore_versions else req if r not in other_reqs and r not in excludes: results['stale'].append(req) return resultsdef diff(r1, r2, include_fresh=False, include_stale=False, excludes=None): include_versions = True if include_stale else False excludes = excludes if len(excludes) else [] try: #生成两个Requirements实例 r1 = Requirements(r1) r2 = Requirements(r2) except ValueError: #加载文件出错,退出 print('There was a problem loading the given requirements files.') exit(os.EX_NOINPUT) results = r1.diff(r2, ignore_versions=True, excludes=excludes) #进行diff if include_fresh: for line in results['fresh']: print(line.name if include_versions else line) if include_stale: for line in results['stale']: print(line.name if include_versions else line)def main(): args = docopt(__doc__, version='pip-diff') #生成字典,key为Docstrings里面的描述的参数 kwargs = { 'r1': args['<reqfile1>'], 'r2': args['<reqfile2>'], 'include_fresh': args['--fresh'], 'include_stale': args['--stale'], 'excludes': args['<package>'] } diff(**kwargs)if __name__ == '__main__': #在其他文件中导入这个文件,讲不会运行main函数 main()
未完待续。。。
0 0
- pip-pop源码阅读笔记
- pip-pop源码分析
- facebook开源动画引擎 pop 源码阅读笔记:
- LZ77源码阅读笔记
- Boa 源码阅读笔记
- VNC源码阅读笔记
- osqa源码阅读笔记
- VNC源码阅读笔记
- MPlayer 源码阅读笔记
- PyEmu源码阅读笔记
- JSONModel源码阅读笔记
- JSONModel源码阅读笔记
- HSF源码阅读笔记
- memcached 源码阅读笔记
- ALLJOYN源码阅读笔记
- netmap源码阅读笔记
- ArrayList源码阅读笔记
- Flask 源码阅读笔记
- 原型链总结
- 《OpenCV3编程入门》学习笔记之官方例程学习
- 杭电1003
- spark rdd详解二(transformation与action操作)
- 屏蔽网易博客碍眼的注册窗口
- pip-pop源码阅读笔记
- Android Studio遇到的问题
- nhibernate的关系
- Queue Reconstruction by Height
- codevs 3290 noip 2013 Day2 T3华容道
- ajax异步刷新上传文件
- UOJ #35. 后缀排序(后缀数组模板题)
- c++初学之面向对象
- 453. Minimum Moves to Equal Array Elements