2014-10-09 16 views
0

我目前正在研究手写识别研究项目(我的学士论文)。我到目前为止写了很多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)? 

我通过scriptssetup.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': '[email protected]', 
    '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文件夹中的脚本并将它们全部添加为子命令?

回答

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使用​​来处理主界面和许多魔术命令。它使用来自配置文件的参数和值填充其解析器。这样可以使用默认配置,自定义配置或在命令行上设置大量参数。

+0

我刚刚尝试过,乍一看它似乎工作。我不得不从'if __name __ =='__ main __':'block之外的backup.py和view.py中移动'parser = ArgumentParser(description = __ doc __)'和相关的东西,但是这样可以。但是,当我想执行'hwrt backup -whatever parameter'时,它不执行。我想问题是“执行”部分仍然在'if __name __ =='__ main __''之下。所以我从view.py和backup.py中彻底删除了'if __name __ =='__ main __''。但是'./hwrt --help'只显示'backup.py'。 – 2014-10-09 20:49:13

+0

是的,'backup.py'(和'view.py')必须进行组织,以便解析器创建者代码和主执行代码是可导入的。只有实际的'parse_args'和主要主代码的调用才会被'if main'所保护。我想我的代码应该以相同的方式组织 - 因此它也可以被导入! – hpaulj 2014-10-09 22:04:01

+0

另一种方法是使用'parse_know_args'来找出要运行的脚本,然后调用'备份。py'或'view.py'作为单独的进程(使用'subprocess'或'multiprocessing'),给它们未知的参数字符串。 – hpaulj 2014-10-09 22:12:31