python 常用的模块 optparse与ConfigParser

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介:

一、optparse 模块

  功能:optparse模块用于处理命令行参数

        使用流程:

    1、首先,必须 import OptionParser 类,创建一个 OptionParser 对象:

1
2
3
4
from optparse  import  OptionParser
 
def Opt ():
    parser=OptionParser( "Usage: %prog -o option -d domain -s subject" )

   2、使用 add_option 来定义命令行参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    parser.add_option( "-d" ,
                       "--domain" ,
                       dest= "domain" ,
                       default=False,
                       action= "store_true" ,
                       help= "special domain_name or domain_name/user" ,)
    parser.add_option( "-s" ,
                       "--subject" ,
                       dest= "subject" ,
                       default=False,
                       action= "store_true" ,
                       help= "special subject for record operational log" ,)
    parser.add_option( "-o" ,
                       "--operation" ,
                       dest= "operation" ,
                       default=False,
                       action= "store_true" ,
                       help= "special operation Del or Insert Key " ,)
    options,args = parser.parse_args()
    return  options,args
    #以上是定义参数与选项,返回对象与参数

    选项说明:

     每个命令行参数就是由参数名字符串和参数属性组成的。如 -d 或者 --domain 分别是长短参数名 

     dest: 是可选的。如果没有指定 dest 参数,将用命令行的参数名来对 options 对象的值进行存取

     store:有两种形式:store_true和store_false,用于处理带命令行参数后面不带值的情况。如 -v,-q [-v 也可以认为查看版本-q表示退出时后面可以不带值] 

     default:可以为参数指定默认值;如果-f表示文件,但没有指定值,那么在解析时会直接找到default定义的默认值。

     action是parse_args()方法的参数之一,它指示optparse当解析到一个命令行参数时该如何处理。actions 有一组固定的值可供选择,默认是'store',表示将命令行参数值保存在 options 对象里。

     help:定义帮助信息,是对参数的描述


   3、生产中使用的完整例子:

    这个脚本的功能其实就是对redis添加删除操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
#!/usr/bin/env python
#coding:utf-8
#Date: 2015-09-09
#Author:king.gp 
################描述#################
#
#查找是否设置此kye,有则跳过
#如果没有设置此kye,并将操作写入/var/log/redis_add_pause_domain_list.log中
#如果恢复指定的存在的key,也要写入到/var/log/redis_retrieve_pause_domain_list.log
#
####################################
 
import  redis
import  datetime
import  os
import  sys
from optparse  import  OptionParser
 
def Opt ():
    parser=OptionParser( "Usage: %prog -o option -d domain -s subject" )
    parser.add_option( "-d" ,
                       "--domain" ,
                       dest= "domain" ,
                       default=False,
                       action= "store_true" ,
                       help= "special domain_name or domain_name/user" ,)
    parser.add_option( "-s" ,
                       "--subject" ,
                       dest= "subject" ,
                       default=False,
                       action= "store_true" ,
                       help= "special subject for record operational log" ,)
    parser.add_option( "-o" ,
                       "--operation" ,
                       dest= "operation" ,
                       default=False,
                       action= "store_true" ,
                       help= "special operation Del or Insert Key " ,)
    options,args = parser.parse_args()
    return  options,args,parser
    #以上是定义参数与选项,返回对象与参数
 
def Connect_Redis(options, hostname ,parser,*argv):
    r = redis.Redis(host= 'localhost' ,port=6379,db= '0' )
    if  options.domain:
      key_string =  hostname + '/Conf/MailBox/' +argv[1]+ '/Status_Pause_All'
      key_list=r.keys(key_string)
      if  (options.operation and  argv[0]== 'search' ):
        if  len(key_list) > 0 :
          print key_list[0]+ ' Existing' 
        else :
          print key_string+ ' Not Existing'
        sys. exit (0)   
 
      if  (options.operation and options.subject and argv[0]== 'delete' ): 
         if   len(key_list)>0:
            r.delete(key_string)
          #print key_string
            print key_string+ ' alrealy Del!'
            with  open ( '/var/log/redis_retrieve_pause_domain_list.log' , 'a' ) as f:
              now = datetime.datetime.now()  
              date_string = now.strftime( "%Y-%m-%d %H:%M:%S" )
              f.write(date_string+ '\t' +argv[2]+ '\t' +key_string+ '\n'
            sys. exit (0)
         else
            print key_string+ ' Not Existing'
            sys. exit (0)
      elif  (options.operation and options.subject and argv[0] == 'insert' ):
           r. set (key_string, '1' )
           print key_string+ ' alrealy Set!'
           with  open ( '/var/log/redis_add_pause_domain_list.log' , 'a' ) as f:
             now = datetime.datetime.now()  
             date_string = now.strftime( "%Y-%m-%d %H:%M:%S" )
             f.write(date_string+ '\t' +argv[2]+ '\t' +key_string+ '\n' )
           sys. exit (0)
      else :
         parser.error( "domain or subject not empty" )
 
    else :
       sys. exit (0)
 
def Get_Host_Name():
   host = os.popen( 'echo $HOSTNAME' )
   hostname  = host. read ().strip()
   if  len( hostname ) > 4:
     hostname  hostname . split ( '.' )[0]
   return  hostname
 
def main():
     options,args,parser=Opt()
     if  args:
       keys=tuple(args)
       hostname =Get_Host_Name()
       Connect_Redis(options, hostname ,parser,*keys)
     else  :
       parser.error( "Usage: %prog -o option -d domain -s subject" )
     
if  __name__ ==  '__main__' :
     main()

  4、查看帮助

1
2
3
4
5
6
7
8
[root@mx1 yunwei] # python change_redis_pause_key.py  -h
Usage: change_redis_pause_key.py -o option -d domain -s subject
 
Options:
   -h, --help       show this help message and  exit
   -d, --domain     special domain_name or domain_name /user
   -s, --subject    special subject  for  record operational log
   -o, --operation  special operation Del or Insert Key

二、ConfigParser模块

  1、功能:配置文件解析模块【我是这么理解的】

  2、说明:配置文件要mysql的配置文件一样分区段;配置文件的格式:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。

      3、函数说明:

    • 读取配置文件时的函数

1
2
3
4
5
6
read (filename) 直接读取ini文件内容
sections() 得到所有的section,并以列表的形式返回
options(section) 得到该section的所有option
items(section) 得到该section的所有键值对
get(section,option) 得到section中option的值,返回为string类型
getint(section,option) 得到section中option的值,返回为int类型,还有相应的getboolean()和getfloat() 函数。
    • 写入文件时的函数

1
2
add_section(section) 添加一个新的section
set ( section, option, value) 对section中的option进行设置,需要调用write将内容写入配置文件。
    • 保存文件

1
conf.write( open (network_path+network_card, 'w' ))

  4、写个例子

   说明:迁移机房生成原IP与新IP的绑定到对应的配置文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
bash -4.1$  cat  network.py 
#!/usr/bin/env python
#conding:utf8
 
#
import  sys
import  os
import  commands
import  ConfigParser
 
class Netconf(ConfigParser.ConfigParser):
     def __init__(self,default=None):
        ConfigParser.ConfigParser.__init__(self,defaults=None)
     def optionxform(self,optionstr):
        return  optionstr
 
def Def_Network(source_ip,network_card):
     str_card=network_card[:10]+ '\\' +network_card[10:]  #定义DEVICE:eth0:x
     network_path= '/home/sysadmin/proxy_config/'
     network_template= 'ifcfg-ethx'
     network_full_path=network_path+network_template
     conf=Netconf()
     conf. read (network_full_path) 
     conf. set ( "network_card" , "IPADDR" ,source_ip)
     conf. set ( "network_card" , "DEVICE" ,network_card[6:])
     conf.write( open (network_path+network_card, 'w' ))
     cmd = "sed -i 's@ @@g' " +network_path+str_card
     (s,r)=commands.getstatusoutput(cmd)
     if  s ==0:
       print  "Success"
       #['ipv6init', 'userctl', 'dns2', 'dns1', 'ipaddr', 'onboot', 'netmask', 'device', 'type', 'gateway']
 
def main():
   source_file= '/home/sysadmin/proxy_config/unix_proxy.txt'
   if  os.path.exists(source_file):
      with  open (source_file) as fn:
         data = fn.readlines()
         #print type(data)
         for  ethx   in  data:
            ethx=ethx. split ( '\t' )
            C_IP=ethx[0].strip()
            N_IP=ethx[1].strip() 
            W_Card=ethx[2].strip()
            Def_Network(C_IP,W_Card)    
   else :    
     print  " %s file not found"  %source_file
 
 
if  __name__== '__main__' :
     main()

 注:遇到的问题,可能在其它服务的配置文件里不算什么问题,但是,在网卡设置中这是一个大的问题

    • 参数的大小写;ConfigParser模块中将所有读取的Key都变成了小写,而网卡的配置文件必须是大写;请查看ConfigParser模块的文件【我的是centos6.3x86_64系统,环境python2.6.6,路径为

/usr/lib64/python2.6/ConfigParser.py】

   如果要解决这个问题有两种方式:

     第一:要修改ConfigParser.py文件中的将return optinostr.lower()改成return optionstr即可。

1
2
354     def optionxform(self, optionstr):
355          return  optionstr.lower()

     第二:通过类继承,重写optionxfrom方法。

     至于使用那种方法,请根据实际情况而定。

    • 生成的配置文件中,key = value等号两端有空格,配置文件不认,只好用sed命令替换了

  5、原文件unix_proxy

1
2
1.2.3.4  192.168.2.4   ifcfg-eth0:0
5.6.7.8  192.168.2.8   ifcfg-eth0:1

  6、模板文件ifcfg-ethx

1
2
3
4
5
6
7
8
9
10
[network_card]
DEVICE=eth0
ONBOOT= yes
TYPE=Ethernet
IPADDR=1.2.3.4
NETMASK=255.255.254.0
DNS2=1.2.4.8
GATEWAY=1.2.3.1
IPV6INIT=no
USERCTL=no

运行脚本即可绑定网卡的配置文件 


三、总结

 1、要多写,多看【标准库】这里有中文版本的,有能力的小伙伴可以去试着翻译一下 http://python.usyiyi.cn/python_278/tutorial/index.html

 2、承认自己的不足,才能进步

 3、多总结










本文转自 jinlinger 51CTO博客,原文链接:http://blog.51cto.com/essun/1708137,如需转载请自行联系原作者
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
57 4
|
20天前
|
Python
Python Internet 模块
Python Internet 模块。
118 74
|
2月前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
118 63
|
2月前
|
测试技术 Python
手动解决Python模块和包依赖冲突的具体步骤是什么?
需要注意的是,手动解决依赖冲突可能需要一定的时间和经验,并且需要谨慎操作,避免引入新的问题。在实际操作中,还可以结合使用其他方法,如虚拟环境等,来更好地管理和解决依赖冲突😉。
|
2月前
|
持续交付 Python
如何在Python中自动解决模块和包的依赖冲突?
完全自动解决所有依赖冲突可能并不总是可行,特别是在复杂的项目中。有时候仍然需要人工干预和判断。自动解决的方法主要是提供辅助和便捷,但不能完全替代人工的分析和决策😉。
|
2月前
|
JSON Linux 数据格式
Python模块:从入门到精通,只需一篇文章!
Python中的模块是将相关代码组织在一起的单元,便于重用和维护。模块可以是Python文件或C/C++扩展,Python标准库中包含大量模块,如os、sys、time等,用于执行各种任务。定义模块只需创建.py文件并编写代码,导入模块使用import语句。此外,Python还支持自定义模块和包,以及虚拟环境来管理项目依赖。
Python模块:从入门到精通,只需一篇文章!
|
2月前
|
Python
Python的模块和包
总之,模块和包是 Python 编程中非常重要的概念,掌握它们可以帮助我们更好地组织和管理代码,提高开发效率和代码质量
45 5
|
2月前
|
数据可视化 Python
如何在Python中解决模块和包的依赖冲突?
解决模块和包的依赖冲突需要综合运用多种方法,并且需要团队成员的共同努力和协作。通过合理的管理和解决冲突,可以提高项目的稳定性和可扩展性
|
2月前
|
JavaScript 前端开发 Python
python中的OS模块的基本使用
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。博客分享前端技术及全栈开发经验,持续更新中,期待您的关注和支持!🎉🎉🎉
40 0
|
2月前
|
JavaScript 前端开发 Python
python中的platform模块的基本使用
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。博客分享前端技术,助你成长。关注我,持续更新中!🎉🎉🎉
28 0