pip-grep

2019/05/12 14:51
阅读数 17

Pip-pop


pip-grep主要是用于方便查看Requirements.txt中那些模块是安装了的。也就是通过输入的然后模块名称然后在Requirements.txt中进行查询。里面比较难的就是docopt这个模块。

docopt:

docopt 本质上是在 Python 中引入了一种针对命令行参数的形式语言,在代码的最开头使用 """ """文档注释的形式写出符合要求的文档,就会自动生成对应的parse。来看下具体使用的例子:

"""

Usage:

func_test1.py para <abc>

func_test1.py [-vc] <content>

func_test1.py [-f] [FILE] ...


Options:

-h --help

-v --version

-c --control

-f --file_name

"""


from docopt import docopt


if __name__=="__main__":

argu=docopt(__doc__)

print(argu['FILE'])


1 首先构造__doc__的内容,也就是程序开头””” ”””的内容

2 构造Usage,所谓的Usage就是使用方法的格式,docopt会根据Usage里面的格式来解析命令行。格式第一个参数是func_test1.py, 这个就是文件名。第二个参数有集中形式,首先来看func_test1.py para <pa> 这个para没有任何括号包含,证明是必须要带的选项。

使用的命令 python3 func_test1.py para abc, 此时命令匹配到func_test1.py para <pa> 尖括号包括起来的pa就是要被赋值的参数,此时pa=abc


接来下再看func_test1.py [-vc] <content>的格式,此时有括号将-vc包含起来,说明-vc是可选的,-vc也就是-v -c 这两个参数必须包含在Options中。

使用的命令

python3 func_test1.py -vc python 或者是python3 func_test1.py python


最后来看func_test1.py [-f] [FILE] ... 的格式,此时有一个...代表元素可以重复出现,最后解析的结果是一个列表。

使用的命令

python3 func_test1.py -f 1.txt 2.txt

此时FILE被赋值为[1.txt 2.txt], 是一个列表


最后docopt的返回结果是一个字典,返回的内容如下:

当对应的参数不存在的时候,对应的值会被置为False, 比如--control--file_name。而--version则被置为True

python3 func_test1.py -v 1.txt

{'--control': False,

'--file_name': False,

'--version': True,

'<pa>': None,

'<content>': '1.txt',

'FILE': [],

'para': False


同样的para置为Truepa被置为abc

python3 func_test1.py para abc

{'--control': False,

'--file_name': False,

'--version': False,

'<pa>': 'abc',

'<content>': None,

'FILE': [],

'para': True}


--file_name被置为TrueFILE被置为[1.txt 2.txt]

python3 func_test1.py -f 1.txt 2.txt

{'--control': False,

'--file_name': True,

'--version': False,

'<pa>': None,

'<content>': None,

'FILE': ['1.txt', '2.txt'],

'para': False}


总结一下docopt的用法:

Usage中用到的一些标识的含义,正确地使用他们能够更好的完成解析任务:


[]

代表可选的元素,方括号内的元素可有可无


()

代表必须要有的元素,括号内的元素必须要有,哪怕是多个里面选一个。


|

互斥的元素,竖线两旁的元素只能有一个留下


代表元素可以重复出现,最后解析的结果是一个列表


[options]

指定特定的选项,完成特定的任务


另外格式方面Usage:Options:必须要用一个空行隔开

像下面的这种格式会导致解析错误

"""

Usage:

func_test1.py para <pa>

func_test1.py [-vc] <content>

func_test1.py [-f] [FILE] ...

Options:

-h --help

-v --version

-c --control

-f --file_name

"""


正确的格式:

"""

Usage:

func_test1.py para <pa>

func_test1.py [-vc] <content>

func_test1.py [-f] [FILE] ...


Options:

-h --help

-v --version

-c --control

-f --file_name

"""


下面就是主体代码:


class Requirements(object):

def __init__(self, reqfile=None):

super(Requirements, self).__init__()

self.path = reqfile

self.requirements = []


if reqfile:

self.load(reqfile)


def __repr__(self):

return '<Requirements \'{}\'>'.format(self.path)


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):

# 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 grep(reqfile, packages, silent=False):

try:

r = Requirements(reqfile)

except ValueError:

if not silent:

print('There was a problem loading the given requirement file.')

exit(os.EX_NOINPUT)


for req in r.requirements:

if req.name in packages:

if not silent:

print('Package {} found!'.format(req.name))

exit(0)


if not silent:

print('Not found.')


exit(1)



def main():

args = docopt(__doc__, version='pip-grep')


kwargs = {'reqfile': args['<reqfile>'], 'packages': args['<package>'], 'silent': args['-s']}


grep(**kwargs)

args保存的是输入的参数,reqfile就是Requirement.txtpackage就是需要查询的模块名称。


1 Requirements中将所有在Requirement.txt中的模块保存在 self.requirements列表中

2 然后在grep中查找对应的模块名。







 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部