如何构建子命令来捆绑应该独立工作的脚本?

时间:2014-10-09 12:43:43

标签: python setuptools argparse

我目前正在研究手写识别的研究项目(我的学士论文)。到目前为止,我写了很多Python脚本,我想让它们对其他人有用。所以我在PyPI上创建了一个项目:https://pypi.python.org/pypi/hwrt/

目前,只有2个可执行脚本:backup.pyview.py。当通过pip安装它时,我可以调用它们,这样就可以了:

$ backup.py --help
usage: backup.py [-h] [-d FOLDER] [-s] [-o]

Download raw data from online server and back it up (e.g. on dropbox)
handwriting_datasets.pickle.

optional arguments:
  -h, --help            show this help message and exit
  -d FOLDER, --destination FOLDER
                        where do write the handwriting_dataset.pickle
                        (default: /home/moose/Downloads/write-math/archive
                        /raw-datasets)
  -s, --small           should only a small dataset (with all capital letters)
                        be created? (default: False)
  -o, --onlydropbox     don't download new files; only upload to dropbox
                        (default: False)

$ view.py --help
usage: view.py [-h] [-i ID] [--mysql MYSQL] [-m FOLDER]

Display a raw_data_id.

optional arguments:
  -h, --help            show this help message and exit
  -i ID, --id ID        which RAW_DATA_ID do you want?
  --mysql MYSQL         which mysql configuration should be used?
  -m FOLDER, --model FOLDER
                        where is the model folder (with a info.yml)?

我是通过scripts中的setup.py得到的:

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

config = {
    'name': 'hwrt',
    'version': '0.1.19',
    'author': 'Martin Thoma',
    'author_email': 'info@martin-thoma.de',
    'packages': ['hwrt'],
    'scripts': ['bin/backup.py', 'bin/view.py'],
    'url': 'https://github.com/MartinThoma/hwrt',
    'license': 'MIT',
    'description': 'Handwriting Recognition Tools',
    'long_description': """A tookit for handwriting recognition. It was
    developed as part of the bachelors thesis of Martin Thoma.""",
    'install_requires': [
        "argparse",
        "theano",
        "nose",
    ],
    'keywords': ['HWRT', 'recognition', 'handwriting', 'on-line'],
    'download_url': 'https://github.com/MartinThoma/hwrt',
}

setup(**config)

但是,我宁愿让它们像这样被调用:

$ hwrt backup --help
(just what came before for 'backup.py --help')
$ hwrt view --help
(just what came before for 'view.py --help')
$ hwrt --help
(a list of all sub-commands)

我知道这可以通过子命令和argparse来完成。但是,这意味着我必须创建一个新脚本,我将所有命令捆绑到argparse中。但我也希望脚本能够独立工作。对于我来说,仅在backup.py而不是在另一个文件中调整仅对backup.py重要的命令行参数感觉更合乎逻辑。

有没有办法调整我的脚本,以便他们发现" bin文件夹中的脚本并将它们全部添加为子命令?

1 个答案:

答案 0 :(得分:0)

使用parents时可能会出现这种情况。

例如,假设您的两个脚本在加载时都创建了一个parser对象(或者有一个创建解析器的函数):

import argparse
from backup import parser as backup_parser
from view import parser as view_parser

if __name__=='__main__':
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='cmd')
    # or use the parser.setdefault() as described in the documentation
    backup = subparsers.add_parser('backup', add_help=False, parents=[backup_parser])
    view = subparsers.add_parser('view', add_help=False, parents=[view_parser])
    args = parser.parse_args()

这应该打印适当的帮助。 args.cmd将标识子命令,其他属性将是相应的参数。 backup子分析器将是从backup.py导入的解析器的克隆。 (我没有测试过这个脚本所以可能会有一些拼写错误或错误,但它提供了一般的想法。)

How to handle CLI subcommands with argparse讨论了几种处理子命令的方法。

Ipython使用argparse来处理主界面和许多魔术命令。它使用配置文件中的参数和值填充其解析器。这样,可以使用默认配置,自定义配置或命令行设置大量参数。