Chinaunix首页 | 论坛 | 博客
  • 博客访问: 158813
  • 博文数量: 45
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 273
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-28 10:30
文章分类
文章存档

2017年(6)

2016年(3)

2015年(8)

2014年(28)

我的朋友

分类: LINUX

2014-08-07 17:13:04

一、gopts.opt
在create.py文件中,gopts这个全局实例的操作太多了,这里之选择其中的一个分析
  1. gopts.opt('defconfig', short='f', val='FILE',
  2.           fn=set_value, default='xmdefconfig',
  3.           use="Use the given Python configuration script."
  4.           "The configuration script is loaded after arguments have been "
  5.           "processed. Each command-line option sets a configuration "
  6.           "variable named after its long option name, and these "
  7.           "variables are placed in the environment of the script before "
  8.           "it is loaded. Variables for options that may be repeated have "
  9.           "list values. Other variables can be set using VAR=VAL on the "
  10.           "command line. "
  11.           "After the script is loaded, option values that were not set "
  12.           "on the command line are replaced by the values set in the script.")

  13. gopts.default('defconfig')
直接看opts类的opt方法,
  1.  def opt(self, name, **args):
  2.     """Add an option.

  3.         name option name
  4.         **args keyword params for option constructor
  5.         """
  6.         x = Opt(self, name, **args)
  7.         self.options.append(x)
  8.         self.options_map[name] = x
  9.         return x
这个方法没有什么难理解的地方,穿件一个Opt类的实例,把它加到gopt的options链表中,和options_map字典中。在看Opt的构造函数之前,顺带开一下这里的**args的用法。
        python中的这两个常用在作为函数的参数。我们都知道在python中的函数的参数传入方法有两种,一中是在调用时直接传入实参,不写形参的名字,此时,python将按照实参的顺序自动给相应的形参赋值,这是不支持跳跃赋值的。还有另外一种调用方法,在调用函数,传参数时把形参的名字也带上,比如foo(key=value)的形式(key是形参名,value是实参值),这种调用形式将不考虑形参和实参的顺序,而是按照调用时制定关系给形参赋值。
        这样就对应了*args和**kwargs这两种用法。详细的不罗嗦了,看一下下面的例子都理解了。
  1. #!/usr/bin/python

  2. def foo(* args ,**kwargs):
  3.     print "args,", args
  4.     print "kwargs,",kwargs
  5.     print '****************'

  6. def foo2(a = 1,b =2,c=3):
  7.     print 'a=:',a
  8.     print 'b=:',b
  9.     print 'c=:',c
  10.     print "****************"
  11. if __name__ == "__main__":
  12.     foo(1,2,3)
  13.     foo(a = 1,b = 2,c = 3)
  14.     foo(1,2,3,a = 1,b = 2,c = 3)
  15.     foo(1,'b','c' ,a=1,b='b',c='c')
  16.     args=(4,5,6)
  17.     foo2(*args)
  18.     kwargs={'a':4,'b':5,'c':6}
  19.     foo2(**kwargs)
  20. 执行结果:
  21. args, (1, 2, 3)
    kwargs, {}
    ****************
    args, ()
    kwargs, {'a': 1, 'c': 3, 'b': 2}
    ****************
    args, (1, 2, 3)
    kwargs, {'a': 1, 'c': 3, 'b': 2}
    ****************
    args, (1, 'b', 'c')
    kwargs, {'a': 1, 'c': 'c', 'b': 'b'}
    ****************
    a=: 4
    b=: 5
    c=: 6
    ****************
    a=: 4
    b=: 5
    c=: 6
    ****************

        接着看Opt类的构造方法吧。
  1. def __init__(self, opts, name, short=None, long=None,
  2.                  val=None, fn=None, use=None, default=None):
  3.         """Create an option.

  4.         opts parent options object
  5.         name name of the field it controls
  6.         short short (1-char) command line switch (optional)
  7.         long long command-line switch. Defaults to option name.
  8.         val string used to print option args in help.
  9.                 If val is not specified the option has no arg.
  10.         fn function to call when the option is specified.
  11.         use usage (help) string
  12.         default default value if not specified on command-line
  13.         """
  14.         self.opts = opts
  15.         self.name = name
  16.         self.short = short
  17.         if long is None:
  18.             long = name
  19.         self.long = long
  20.         self.val = val
  21.         self.use = use
  22.         self.default = default
  23.         self.optkeys = []
  24.         if self.short:
  25.             self.optkeys.append('-' + self.short)
  26.         if self.long:
  27.             self.optkeys.append('--' + self.long)
  28.         self.fn = fn
  29.         self.specified_opt = None
  30.         self.specified_val = None
  31.         self.value = None
  32.         self.set(default)
这个构造方法,只需要关注两条语句。其一:第15行的self.opts=opts,从参数和传于的参数可见,这里的self的opts指向的Opts类的实例,这里当然就gopt这个全局实例了。其二:第33行self.set(default)。我们需要技术的deault这里传入的值是"xmdeconfig"

  1. def set(self, value):
  2.         """Set the option value.
  3.         """
  4.         self.opts.setopt(self.name, value)
set函数调用opts的setopt方法,opts就是gopts了。name和value就是deconfig和xmdeconfig了。现在继跟踪到Opts类的setopt方法


  1. def setopt(self, name, val):
  2.         """Set an option value.
  3.         An option can also be set using 'opts.vals.name = val'.
  4.         """
  5.         setattr(self.vals, name, val)
这个函数的功能就是向gopts这个实例的vals添加属性。在Opts类的__init__方法中有一句self.vals=OptVals(),所以gopt这个实例有一个OptVals类型的成员。但是OptVals这个类基本没有任何属性,它的实例的属性就是通过setopt方法来添加的。在setopt这个函数中掉用了setattr这个python内置的函数。这个函数与getattr一起,是很有用的两个函数。
        先说setattr这个函数,原型:setattr(object,name,value)。其中object为实例,name为我们要为这个object添加的属性的名字,value就是我们要为这个object添加的name的值。、
        对于getattr这个函数,原型:getattr(object,name,default_value),及获得object的名为name的属性的值,如果没有名为name的值,就放回default_value.
        所以对于setopt,就是为了给Opts的实例的vals添加一个属性。对于gopts,执行完成之后就为器vals添加了一个deconfig=xmconfig这样的一个属性。
        现在继续回到Opts的opt函数,现在到这两条语句了
         self.options.append(x) 
          self.options_map[name] = x
    这两句把刚创建的x添加到options和options_map中。
至此Opts的opt方法就完成了,现在看create.py文件中的gopt.default('deconfig')吧。这个函数很简单,但是为了后面分析方便,这里还是要贴一下源码

  1. def default(self, name):
  2.         self.default_opt = name
这个后面用到了在说吧。






阅读(1302) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~