有什么方法可以指示 argparse (Python 2.7) 从 sys.argv 中删除找到的参数? [英] Is there any way to instruct argparse (Python 2.7) to remove found arguments from sys.argv?

查看:34
本文介绍了有什么方法可以指示 argparse (Python 2.7) 从 sys.argv 中删除找到的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我完全处于开发过程的中游,该项目正在变成一个相当重要的 Python 2.7 项目.现在我所有的 unittest 类都集中了一起放在他们自己的模块中,tests.py,大约有 3300 行.这太疯狂了,无法导航,到处都是不好的做法,等等.

I'm fully midstream in the development process for what is turning into a fairly substantial Python 2.7 project. Right now I have all of my unittest classes lumped together in their own module, tests.py, which stands at about 3300 lines. This is crazy big, impossible to navigate, all around bad practice, etc.

所以,我当前的任务是将其重构为子模块.作为重构的一部分,我想让从命令行运行测试的子集变得容易.例如:

So, my current task is to refactor it into submodules. As part of this refactoring, I want to make it easy to just run a subset of the tests from the commandline. For example:

$ python tests.py --all                         <--- runs *all* tests
$ python tests.py --utils_base                  <--- runs all tests on .utils
$ python tests.py --utils_vector                <--- runs all tests on .utils.vector
$ python tests.py --utils_base --utils_vector   <--- runs all tests on .utils.vector & .utils

所以,我开始使用 argparse.我设置了一个基本的 ArgumentParser 没有问题,帮助信息显示得很好:

So, I started getting things set up with argparse. I got a basic ArgumentParser set up without a problem, and the help message showed just fine:

$ python tests.py -h
usage: tests.py [-h] [--all] [--utils_base]

optional arguments:
  -h, --help    show this help message and exit

Global Options:
  --all         Run all tests (overrides any other selections)

opan.base.utils Tests:
  --utils_base  Run all .utils tests

但是,当我去运行一些测试时,它崩溃了,并出现了无法识别参数"的错误:

However, when I went to run some tests, it crashed out with an 'argument not recognized' error:

$ python tests.py --all
option --all not recognized
Usage: tests.py [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output
  -f, --failfast   Stop on first failure
  -c, --catch      Catch control-C and display results
  -b, --buffer     Buffer stdout and stderr during test runs

Examples:
  tests.py                               - run default set of tests
  tests.py MyTestSuite                   - run suite 'MyTestSuite'
  tests.py MyTestCase.testSomething      - run MyTestCase.testSomething
  tests.py MyTestCase                    - run all 'test*' test methods
                                               in MyTestCase

经过一些调试,我终于意识到要在 tests.py 中解析的命令行参数被保留在 sys.argv 中并传递给 unittest.main.(回想起来,仔细阅读错误消息的 Examples: 部分应该可以让我更早了解.)

After some debugging, I finally realized that my commandline arguments to be parsed within tests.py were being retained in sys.argv and passed through to unittest.main. (In retrospect, a careful read of the Examples: section of the error message should have clued me in a lot sooner.)

因此,为了解决这个问题,我在下面添加了标记的代码,以便在将控制权传递给 unittest.main 之前从 sys.argv 中清除我的自定义参数:

So, to resolve the problem, I added the marked code in the following to scrub my custom arguments from sys.argv before passing control into unittest.main:

# Arguments for selecting test suites
ALL = 'all'
UTILS_BASE = 'utils_base'

# Collecting the args together for iteration later
test_args = [ALL, UTILS_BASE]

...

# Strip from sys.argv any test arguments that are present
for a in test_args:                 <---  
    str_arg = '--{0}'.format(a)     <--- ADDING THESE MAKES UNITTEST HAPPY
    if str_arg in sys.argv:         <---
        sys.argv.remove(str_arg)    <---

有没有办法告诉 argparse.remove 它从 sys.argv 中找到的参数,也许在 的构造中>ArgumentParser?我已经搜索了 argparse 文档页面,但我一生都找不到可以做到这一点的选项.

Is there any way to tell argparse to .remove arguments it finds from sys.argv, perhaps in the construction of the ArgumentParser? I've scoured the argparse doc page, but for the life of me can't find an option that'll do it.

推荐答案

你想要 parse_known_args()

from __future__ import print_function
import argparse
import sys

def main():
    print(sys.argv)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument('--all', action='store_true')
    parser.add_argument('--utils_base', action='store_true')

    args, left = parser.parse_known_args()

    sys.argv = sys.argv[:1]+left

    main()

虽然,我必须问.为什么要编写自己的测试运行程序?unittest 模块允许您从 cli 运行特定的测试集:

Although, I must ask. Why are you writing your own test runner? The unittest module allows you to run specific sets of tests from the cli:

# run test from a spefiic class
$ python -m unittest module.tests.group.TestSpecific
# all possible options
$ python -m unittest --help
Usage: python -m unittest [options] [tests]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output
  -f, --failfast   Stop on first failure
  -c, --catch      Catch control-C and display results
  -b, --buffer     Buffer stdout and stderr during test runs

Examples:
  python -m unittest test_module               - run tests from test_module
  python -m unittest module.TestClass          - run tests from module.TestClass
  python -m unittest module.Class.test_method  - run specified test method

[tests] can be a list of any number of test modules, classes and test
methods.

Alternative Usage: python -m unittest discover [options]

Options:
  -v, --verbose    Verbose output
  -f, --failfast   Stop on first failure
  -c, --catch      Catch control-C and display results
  -b, --buffer     Buffer stdout and stderr during test runs
  -s directory     Directory to start discovery ('.' default)
  -p pattern       Pattern to match test files ('test*.py' default)
  -t directory     Top level directory of project (default to
                   start directory)

For test discovery all test modules must be importable from the top
level directory of the project.

如果您在分组和运行测试方面需要更大的灵活性,我建议您查看 鼻子测试

If you need even more flexibility in grouping and running tests, I'd suggest looking at nosetest

这篇关于有什么方法可以指示 argparse (Python 2.7) 从 sys.argv 中删除找到的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆