1

这是我在 python 中编写的脚本的简化视图:

  • 该脚本用于比较两个文件。
  • 必须指定每个文件的类型(本地或远程)(强制
  • 对于本地文件:

    • 必须指定其文件名(强制
    • 可以指定其路径(可选,默认为.
  • 对于远程文件:

    • 必须指定其文件名(强制
    • 必须指定其路径(强制
    • 可以指定布尔标志(可选

所以我想像这样使用它:

compare.py -L local.txt -L local2.txt -p /tmp/

或者

compare.py -L local.txt -R remote.txt -p remoteDir/ --myFlag

所以我需要定义 2 组选项(本地/L 和远程/R),每组都包含自己的一组强制和可选选项。

我还没有找到一种方法来实现这一点optparse(甚至argparse,但如果可能的话,我想坚持使用optparse,因为我正在为 Python 2.6.7 编写脚本)

有什么干净的解决方案吗?

4

2 回答 2

3

我会使用选项回调+帮助器对象来跟踪当前选项的上下文。例子:

from optparse import OptionParser

class FileBase(object):
    def __init__(self, fname):
        self.fname = fname
        self.path = None
class LocalFile(FileBase):
    pass
class RemoteFile(FileBase):
    pass

class FileOptionParser(object):
    def __init__(self):
        self.last_file = None
        self.files = []

    def set_path(self, option, opt, value, parser):
        self.last_file.path = value

    def set_file(self, option, opt, value, parser):
        if   option.dest=="local" : cls = LocalFile
        elif option.dest=="remote": cls = RemoteFile
        else:                       assert False
        self.last_file = cls(value)
        self.files.append(self.last_file)
        setattr(parser.values, option.dest, self.last_file)

fop = FileOptionParser()

parser = OptionParser()
parser.add_option('-L', '--local',  type='string', action='callback', callback=fop.set_file)
parser.add_option('-R', '--remote', type='string', action='callback', callback=fop.set_file)
parser.add_option('-p', '--path',   type='string', action='callback', callback=fop.set_path)

(options, args) = parser.parse_args()
print [(f.fname, f.path) for f in fop.files]

例子是:

> python test.py -L local.txt -R remote.txt -p remoteDir/
[('local.txt', None), ('remote.txt', 'remoteDir/')]
于 2013-05-24T10:38:40.367 回答
0

我认为答案是您不再谈论选项,而是谈论程序的参数选项是可以(可选)用于影响程序行为的修饰符;另一边的参数stdin是程序应处理的输入数据(在某些情况下是附加的)。

话虽如此,我认为您应该将可选的布尔标志设为一个选项,并在optparse完成其工作后解析所有其他信息参数。找出一个简洁的语法来指定什么参数指定一个本地文件和什么指定一个远程文件,例如/path/to/local/filehost:/path/to/remote/file(尽管这种语法被诸如 之类的东西使用rsync,请记住它:在路径名中存在冒号问题)。

于 2013-05-24T10:23:58.327 回答