一半君的总结纸

听话只听一半君

parse comma separated srings to list with optparse ?

基本部分是在stackoverflow搜来的,我自己改了下。
我知道现在该用argparse了,直接就有这功能,但是有很多老的script用的是optparse,要全部改掉太多了
下面的作用是 0.2,0.3这样的会存成[0.2,0.3],而不是[‘0.2′,’0.3’]
还有XYZ1-3会存成[‘XYZ1′,’XYZ2′,’XYZ3’]
都有强迫的检查是不是符合3个大写字母+多个数字这样的规律


class MultipleOption(Option):
    '''
    This will give optparse the ability to store comma separated options as a (float) list
    eg.  -x XYZ1,ABC1 will be stored as ['XYZ1','ABC1']
         -f 0.2,0.5 will be stored as [0.2,0.5]
    '''
    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            lvalue = value.split(",")
            if self.type=='floatList':
                lvalue=[float(v) for v in lvalue]
            elif self.type=='packageList':
                # XYZ1-9
                packageList=[]
                for v in lvalue:
                    if '-' not in v:
                        packageList.append(v)
                    else:
                        try:
                            start=re.search('(?<=[A-Z])\d+(?=-)',v).group()
                            end=re.search('(?<=-)\d+',v).group()
                            package=re.search('^[A-Z]+(?=\d+-)',v).group()
                            s = int(start)
                            e = int(end)
                            if s>e:
                                s,e=e,s
                            packageRange = range(s,e+1)
                            expandedList = ['%s%s'%(package,str(p)) for p in packageRange ]
                            packageList.extend(expandedList)
                        except:
                            packageList.append(v)

                lvalue=packageList

            values.ensure_value(dest, []).extend(lvalue)
        else:
            Option.take_action(
                self, action, dest, opt, value, values, parser)

    @staticmethod
    def is_number(s):
        try:
            float(s)
            return True
        except ValueError:
            return False

    def check_floatList(option, opt, value):
        try:
            for v in value.split(','):
                if not MultipleOption.is_number(v):
                    raise ValueError
            return value
        except ValueError:
            raise OptionValueError(
                "option %s: invalid float list value: %r" % (opt, value))

    def check_packageList(option, opt, value):
        '''
        if - is in the value, then it must be XYZ1-3 format
        (3 uppercase char)(digits)-(digits)
        '''
        try:
            for v in value.split(','):
                if '-' in v:
                    if not re.match('[A-Z]{3}\d+-\d+',v):
                        raise ValueError
            return value
        except ValueError:
            raise OptionValueError(
                "option %s: invalid float list value: %r" % (opt, value))

    TYPES = Option.TYPES + ("floatList","packageList")
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["floatList"] = check_floatList
    TYPE_CHECKER["packageList"] = check_packageList

用的时候是这样

parser = optparse.OptionParser(option_class=MultipleOption)

parser.add_option("-x",
                  action="extend",
                  type="floatList",
                  dest="xDest" )
parser.add_option("-y",
                  dest="yDest", default=None,
                  type="packageList",
                  action="extend")

举例 -x 0.2,0.3 会存成 xDest=[0.2,0.3]
-y ABC1-3,DEF1 会存成 yDest=[‘ABC1’,’ABC2’,’ABC3’,’DEF1’]

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: