【问题标题】:Python Arguments and Passing Floats in ArgumentsPython 参数和在参数中传递浮点数
【发布时间】:2016-10-19 18:56:51
【问题描述】:

我在 python 脚本中使用参数时遇到了几个问题。我能否获得一些帮助或指导以使此代码正常运行?提前谢谢你。

第一个问题:我无法一次指定多个参数。 例如,我可以很好地传递一个参数:

$ ./my_arg_scenario.py -a
Argument_A
$ ./my_arg_scenario.py -c
Argument_C
$ ./my_arg_scenario.py -d
Argument_D

但是,我正在寻找一种在任何位置传递多个参数的方法。有没有办法我可以做到这一点? 例如,我希望发生以下情况:

./my_arg_scenario.py -a -c -d
Argument_A
Argument_C
Argument_D

# OR    

./my_arg_scenario.py -c -a
Argument_C
Argument_A

第二个问题:我试图在 -b 参数中同时传递整数和浮点数。但是当我传递一个浮点数/小数时,我得到以下错误。有没有办法可以同时传递浮点数和整数?

这行得通:

$ ./my_arg_scenario.py -b 5
The number provided is: 5

但这不是:

$ ./my_arg_scenario.py -b 5.50
Traceback (most recent call last):
  File "./my_arg_scenario.py", line 18, in <module>
    if int(sys.argv[2]) not in range(0,11):
ValueError: invalid literal for int() with base 10: '5.50'

下面是我的可测试代码:

#!/usr/local/bin/python3.5
import sys

script_options = ['-a', '-b', '-c', '-d']
manual_flag = ''
build_flag = ''

if len(sys.argv) > 1:
    if sys.argv[1] in script_options:
        pass
    else:
        print('\n\t\tParameter "' + sys.argv[1] + '" is an invalid argument.\n')
        sys.exit()
    if sys.argv[1] == '-a':
        print('Argument_A')
        sys.exit()
    elif sys.argv[1] == '-b':
        if int(sys.argv[2]) not in range(0,11):
            print('Invalid interval. Please select a value bewteen 1-5s.')
            sys.exit()
        else:
            print('The number provided is: ' + (sys.argv[2]))
    elif sys.argv[1] == '-c':
        manual_flag = 'Argument_C'
        print(manual_flag)
    elif sys.argv[1] == '-d':
        build_flag ='Argument_D'
        print(build_flag)
else:
    pass

【问题讨论】:

  • not in range(0,11) 不是范围检查,正确的是 not (0 &lt;= float(sys.argv[2]) &lt;= 11)

标签: python python-3.x int argv


【解决方案1】:

您实际上并没有提供您正在使用的代码(除了偶然在回溯中),更新:稍后添加的代码)但答案是:停止手动解析sys.argv 并使用the argparse module(或docopt 或不涉及滚动您自己的开关解析)。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a', action='store_true')
parser.add_argument('-b', metavar='INTERVAL', type=int, choices=range(11))
parser.add_argument('-c', action='store_true')
parser.add_argument('-d', action='store_true')
args = parser.parse_args()

if args.a: print('Argument_A')
if args.b is not None: print('The number provided is:', args.b)
if args.c: print('Argument_C')
if args.d: print('Argument_D')

如果您想接受intfloat,最简单的解决方案是只制作type=float 并使用一致的类型(但range 检查必须在解析步骤之外进行)。如果您必须同时允许两者,ast.literal_eval 或自制的argparse 类型转换函数是选项。由于您也需要范围检查(range 无法正确处理不等于 int 值的 float 值),请滚动类型检查器:

def int_or_float(minval=None, maxval=None):
    def checker(val):
        try:
            val = int(val)
        except ValueError:
            val = float(val)
        if minval is not None and val < minval:
            raise argparse.ArgumentTypeError('%r must be >= %r' % (val, minval))
        if maxval is not None and val > maxval:
            raise argparse.ArgumentTypeError('%r must be <= %r' % (val, maxval))
        return val
    return checker

然后通过将-b 的定义替换为:

# Might want int_or_float(0, 10) depending on range exclusivity rules
parser.add_argument('-b', metavar='INTERVAL', type=int_or_float(0, 11))

【讨论】:

  • 点击提交太快了。添加了上面的代码。没有用过argparse。如果您有一些好的参考资料,请通过我的方式。
  • @MBasith:好吧,我提供了一个基本示例。否则,我会阅读the docs page for the module that I linked。那里有很多,但是你使用的越多,它就越容易,并且在每个程序中使用它是一个非常好的主意;它还制作了友好的使用语句,这使得首先记住如何使用程序更容易。
  • 感谢您的示例和信息。
  • 感谢您详细说明解决方案。这正是我想要的更多。使用浮动的解决方案令人难以置信。以后肯定会使用 argparse,省去很多麻烦。非常感谢。
猜你喜欢
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 2016-02-08
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多