天天看点

Python [9] optparse模块生成命令行帮助信息

起初,最先接触python命令行传参是sys模块的argv方法,此方法功能简单,稍微增加一些需求,就不难满足需要了

<a href="http://467754239.blog.51cto.com/4878013/1619323" target="_blank">那么今天就和大家聊聊optparse模块来替换sys模块的argv方法</a>

一、optparse官方概述

1

2

3

4

5

<code>optparse </code><code>is</code> <code>a more convenient, flexible, </code><code>and</code> <code>powerful library </code><code>for</code> <code>parsing command</code><code>-</code><code>line options than </code>

<code>the old getopt module. optparse uses a more declarative style of command</code><code>-</code><code>line parsing: you create </code>

<code>an instance of OptionParser, populate it with options, </code><code>and</code> <code>parse the command line. optparse </code>

<code>allows users to specify options </code><code>in</code> <code>the conventional GNU</code><code>/</code><code>POSIX syntax, </code><code>and</code> <code>additionally generates </code>

<code>usage </code><code>and</code> <code>help</code> <code>messages </code><code>for</code> <code>you.</code>

<code>optparse是更加方便,灵活,和用于解析命令行选项比老Getopt模块强大。</code>

<code>optparse使用陈述式的命令行解析:你创建optionparser实例,选择填充它,并解析命令行。</code>

<code>optparse允许用户指定在传统的GNU </code><code>/</code> <code>POSIX语法选项,并生成使用和帮助给你的留言。</code>

二、optparser语法

1. Here’s an example of using optparse in a simple script:

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<code>从optparse模块中导入OptionParse类</code>

<code>from</code> <code>optparse </code><code>import</code> <code>OptionParser</code>

<code>[...]</code>

<code>实例化一个OptionParse对象</code>

<code>parser </code><code>=</code> <code>OptionParser()</code>

<code>调用add_ooption方法并声明参数结构</code>

<code>parser.add_option(</code><code>"-f"</code><code>, </code><code>"--file"</code><code>, dest</code><code>=</code><code>"filename"</code><code>,</code>

<code>                  </code><code>help</code><code>=</code><code>"write report to FILE"</code><code>, metavar</code><code>=</code><code>"FILE"</code><code>)</code>

<code>parser.add_option(</code><code>"-q"</code><code>, </code><code>"--quiet"</code><code>,</code>

<code>                  </code><code>action</code><code>=</code><code>"store_false"</code><code>, dest</code><code>=</code><code>"verbose"</code><code>, default</code><code>=</code><code>True</code><code>,</code>

<code>                  </code><code>help</code><code>=</code><code>"don't print status messages to stdout"</code><code>)</code>

<code>调用parse_args解析参数,返回(option,args)元组</code>

<code>(options, args) </code><code>=</code> <code>parser.parse_args()</code>

<code>parser.parse_args()返回值为两个</code>

<code>options为字典,而args为列表</code>

2.帮助信息展示

测试optparse脚本

<code>[root@python script]</code><code># cat 04_optparse.py </code>

<code>#!/usr/bin/env python</code>

<code>(options, args) </code><code>=</code> <code>parser.parse_args()</code>

执行脚本,获取帮助信息

<code>[root@python script]</code><code># python 04_optparse.py -h</code>

<code>Usage: </code><code>04_optparse</code><code>.py [options]</code>

<code>Options:</code>

<code>  </code><code>-</code><code>h, </code><code>-</code><code>-</code><code>help</code>            <code>show this </code><code>help</code> <code>message </code><code>and</code> <code>exit</code>

<code>  </code><code>-</code><code>f </code><code>FILE</code><code>, </code><code>-</code><code>-</code><code>file</code><code>=</code><code>FILE</code>  <code>write report to </code><code>FILE</code>

<code>  </code><code>-</code><code>q, </code><code>-</code><code>-</code><code>quiet           don't </code><code>print</code> <code>status messages to stdout</code>

3.参数解析

parser.add_option()参数说明:

"-f", "--file":长短选项

action="store":存储方式

<code>存储方式有三种:store,store_false,store_true</code>

<code>action</code><code>=</code><code>"store"</code><code>默认值,将命令行选项后面的值(示例中</code><code>-</code><code>F </code><code>2</code><code>)和dest的值(from_step)组成字典({</code><code>'from_step'</code><code>:</code><code>2</code><code>})并赋值给options,所以options.from_step的值为</code><code>2</code>

<code>action</code><code>=</code><code>"store_true"</code><code>,options.from_step的值是Ture,不是</code><code>2</code>

<code>action</code><code>=</code><code>"store_false"</code><code>,options.from_step的值是</code><code>False</code><code>,不是</code><code>2</code>

type="string":参数类型

dest="filename":存储的变量,即生成字典的key

default:设置参数的默认值

help:帮助信息

metavar:帮助信息中用到

4.详解参数action存储方式

起初我在学习optparse的时候,参数中的存储方式action我一个没有弄明白,为了让大家更清晰的弄清楚,我在这里写个简单的脚本做个测试。

情况1:action='store'

<code>[root@python script]</code><code># vim 07_optparse.py </code>

<code>def</code> <code>opt():</code>

<code>    </code><code>parser </code><code>=</code> <code>OptionParser()</code>

<code>    </code><code>parser.add_option(</code><code>'-l'</code><code>,</code><code>'--local'</code><code>,</code>

<code>                      </code><code>dest</code><code>=</code><code>'local'</code><code>,</code>

<code>                      </code><code>action</code><code>=</code><code>'store'</code><code>,</code>

<code>                      </code><code>help</code><code>=</code><code>'local file or directory'</code><code>)</code>

<code>    </code><code>options, args </code><code>=</code> <code>parser.parse_args()</code>

<code>    </code><code>return</code> <code>options, args</code>

<code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>'__main__'</code><code>:</code>

<code>    </code><code>options, args </code><code>=</code> <code>opt()</code>

<code>    </code><code>print</code> <code>options</code>

<code>    </code><code>print</code> <code>args</code>

执行此脚本:

<code>[root@python script]</code><code># python 07_optparse.py </code>

<code>{</code><code>'local'</code><code>: </code><code>None</code><code>}</code>

<code>[]</code>

<code>[root@python script]</code><code># python 07_optparse.py -h</code>

<code>Usage: </code><code>07_optparse</code><code>.py [options]</code>

<code>  </code><code>-</code><code>l LOCAL, </code><code>-</code><code>-</code><code>local</code><code>=</code><code>LOCAL    </code>

<code>                        </code><code>local </code><code>file</code> <code>or</code> <code>directory</code>

<code>[root@python script]</code><code># python 07_optparse.py -l nihao</code>

<code>{</code><code>'local'</code><code>: </code><code>'nihao'</code><code>}</code>

情况2:action='store_true'

<code>[root@python script]</code><code># cat 07_optparse.py </code>

<code>              </code><code>dest</code><code>=</code><code>'local'</code><code>,</code>

<code>              </code><code>action</code><code>=</code><code>'store_true'</code><code>,</code>

<code>              </code><code>help</code><code>=</code><code>'local file or directory'</code><code>)</code>

<code>  </code><code>-</code><code>h, </code><code>-</code><code>-</code><code>help</code>   <code>show this </code><code>help</code> <code>message </code><code>and</code> <code>exit</code>

<code>  </code><code>-</code><code>l, </code><code>-</code><code>-</code><code>local  local </code><code>file</code> <code>or</code> <code>directory</code>

<code>{</code><code>'local'</code><code>: </code><code>True</code><code>}</code>

<code>[</code><code>'nihao'</code><code>]</code>

情况3:action='store_false'

<code>              </code><code>action</code><code>=</code><code>'store_false'</code><code>,</code>

<code>[root@python script]</code><code># python 07_optparse.py h</code>

<code>[</code><code>'h'</code><code>]</code>

<code>{</code><code>'local'</code><code>: </code><code>False</code><code>}</code>

简论:参数值为store会把你传入的参数作为字典的value,反而store_true和store_false不会。

四、解决上篇博客的问题

脚本的功能:

显示更多丰富的帮助信息

批量上传单个文件到远程主机

批量上传多个文件到远程主机

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

<code>#coding:utf8</code>

<code>from</code> <code>multiprocessing </code><code>import</code> <code>Process</code>

<code>import</code> <code>paramiko</code>

<code>import</code> <code>sys</code>

<code>import</code> <code>os</code>

<code>Username </code><code>=</code> <code>'root'</code>

<code>Password </code><code>=</code> <code>'redhat'</code>

<code>Port </code><code>=</code> <code>22</code>

<code>             </code><code>dest</code><code>=</code><code>'local'</code><code>,</code>

<code>             </code><code>action</code><code>=</code><code>'store'</code><code>,</code>

<code>             </code><code>help</code><code>=</code><code>"local directory's file"</code><code>)</code>

<code>    </code><code>parser.add_option(</code><code>'-r'</code><code>,</code><code>'--remote'</code><code>,</code>

<code>             </code><code>dest</code><code>=</code><code>'remote'</code><code>,</code>

<code>             </code><code>help</code><code>=</code><code>"remote directory's file"</code><code>)</code>

<code>def</code> <code>fdir(ff):</code>

<code>    </code><code>fileList </code><code>=</code> <code>[]</code>

<code>    </code><code>for</code> <code>p, d, f </code><code>in</code> <code>os.walk(ff):</code>

<code>    </code><code>files </code><code>=</code> <code>f</code>

<code>    </code><code>break</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>files:</code>

<code>    </code><code>ii </code><code>=</code> <code>os.path.join(ff,i)</code>

<code>    </code><code>fileList.append(ii)</code>

<code>    </code><code>return</code> <code>fileList</code>

<code>def</code> <code>delgen(path):</code>

<code>    </code><code>try</code><code>:</code>

<code>        </code><code>if</code> <code>path[</code><code>-</code><code>1</code><code>] </code><code>=</code><code>=</code> <code>'/'</code><code>:</code>

<code>            </code><code>path </code><code>=</code> <code>path[:</code><code>-</code><code>1</code><code>]</code>

<code>        </code><code>else</code><code>:</code>

<code>            </code><code>path </code><code>=</code> <code>path</code>

<code>    </code><code>except</code><code>:</code>

<code>    </code><code>sys.exit(</code><code>1</code><code>)</code>

<code>    </code><code>return</code> <code>path</code>

<code>def</code> <code>sftpPut(ip,localDir,rfile):</code>

<code>        </code><code>s </code><code>=</code> <code>paramiko.Transport((ip,Port))</code>

<code>        </code><code>s.connect(username</code><code>=</code><code>Username,password</code><code>=</code><code>Password)</code>

<code>        </code><code>sftp </code><code>=</code> <code>paramiko.SFTPClient.from_transport(s)</code>

<code>        </code><code>sftp.put(localDir,rfile) </code>

<code>    </code><code>s.close()</code>

<code>    </code><code>print</code> <code>'%s put successful.'</code> <code>%</code> <code>ip</code>

<code>    </code><code>print</code> <code>'%s not exists.'</code> <code>%</code> <code>ip</code>

<code>def</code> <code>sftpPuts(ip,localDir,remoteDir):</code>

<code>    </code><code>for</code> <code>localFile </code><code>in</code> <code>localDir:</code>

<code>        </code><code>filebasename </code><code>=</code> <code>os.path.basename(localFile)</code>

<code>        </code><code>remoteFile </code><code>=</code> <code>'%s/%s'</code> <code>%</code> <code>(remoteDir,filebasename)</code>

<code>            </code><code>sftp.put(localFile,remoteFile)</code>

<code>        </code><code>s.close()</code>

<code>def</code> <code>ipProcess01(localFile,remoteFile):</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>2</code><code>,</code><code>255</code><code>):</code>

<code>        </code><code>ip </code><code>=</code> <code>'192.168.0.%s'</code> <code>%</code> <code>i</code>

<code>        </code><code>p </code><code>=</code> <code>Process(target</code><code>=</code><code>sftpPuts,args</code><code>=</code><code>(ip,localFile,remoteFile))</code>

<code>        </code><code>p.start()</code>

<code>    </code> 

<code>def</code> <code>ipProcess02(localDir,rfile):</code>

<code>        </code><code>p </code><code>=</code> <code>Process(target</code><code>=</code><code>sftpPut,args</code><code>=</code><code>(ip,localDir,rfile))</code>

<code>    </code><code>localDir,remoteDir </code><code>=</code> <code>options.local,options.remote</code>

<code>        </code><code>if</code> <code>os.path.isdir(localDir):</code>

<code>            </code><code>fileList </code><code>=</code> <code>fdir(localDir)</code>

<code>            </code><code>remoteDir </code><code>=</code> <code>delgen(remoteDir)</code>

<code>            </code><code>ipProcess01(fileList,remoteDir)</code>

<code>        </code><code>elif</code> <code>os.path.isfile(localDir): </code>

<code>           </code><code>lfile </code><code>=</code> <code>os.path.basename(localDir)</code>

<code>           </code><code>remoteDir </code><code>=</code> <code>delgen(remoteDir)</code>

<code>           </code><code>rfile </code><code>=</code> <code>'%s/%s'</code> <code>%</code> <code>(remoteDir,lfile)</code>

<code>           </code><code>ipProcess02(localDir,rfile)</code>

<code>    </code><code>print</code> <code>'Usage: python %s'</code> <code>%</code> <code>sys.argv[</code><code>0</code><code>]</code>

脚本的帮助信息

<code>[root@python script]</code><code># python 01_optparse_process.py </code>

<code>Usage:python </code><code>01_optparse_process</code><code>.py</code>

<code>[root@python script]</code><code># python 01_optparse_process.py -h</code>

<code>Usage: </code><code>01_optparse_process</code><code>.py [options]</code>

<code>  </code><code>-</code><code>l LOCAL, </code><code>-</code><code>-</code><code>local</code><code>=</code><code>LOCAL</code>

<code>                        </code><code>local directory's </code><code>file</code>

<code>  </code><code>-</code><code>r REMOTE, </code><code>-</code><code>-</code><code>remote</code><code>=</code><code>REMOTE</code>

<code>                        </code><code>remote directory's </code><code>file</code>

上传单个文件到远程服务器

<code># python 01_optparse_process.py -l /path/to/somefile -r /root/</code>

<code>假设,这里有一个需求,将本地</code><code>/</code><code>tmp</code><code>/</code><code>sync.sh这个shell脚本批量上传到远程主机的</code><code>/</code><code>tmp目录下:</code>

<code># python 01_optparse_process.py -l /tmp/sync.sh -r /tmp</code>

上传多个文件(指定目录下所有文件不包括子目录)到远程服务器

<code># python 01_optparse_process.py -l /path/to/directory -r /tmp/</code>

<code>假设,这里有一个需求,将本地某一个备份数据库目录下的所有备份文件(不包括子目录)</code><code>/</code><code>bakckup</code><code>/</code><code>mysql上传到远程主机的</code><code>/</code><code>tmp目录下:</code>

<code># python 01_optparse_process.py -l /backup/mysql -r /tmp/</code>

在实际应用当中,我们可能并不是直接的这么来用,我们可以针对主机根据应用的不同进行分组,然后可以针对某台主机进行上传,也可以针对某一个组进行上传,这样用起来会更舒服,更人性化。所谓事情都是一步步来,后面的章节中会有所介绍。

今天和大家就先聊到这里,我们下篇博客见。

     本文转自zys467754239 51CTO博客,原文链接:http://blog.51cto.com/467754239/1619323,如需转载请自行联系原作者