检查是否设置了argparse可选参数

时间:2015-05-27 16:08:24

标签: python argparse

我想检查用户是否设置了可选的argparse参数。

我可以使用isset安全检查吗?

这样的事情:

if(isset(args.myArg)):
    #do something
else:
    #do something else

对于float / int / string类型参数,这是否有效?

我可以设置一个默认参数并进行检查(例如,设置myArg = -1,或者#34;"表示字符串,或者#34; NOT_SET")。但是,我最终想要使用的值仅在稍后的脚本中计算。所以我将其设置为-1作为默认值,然后将其更新为其他内容。与仅仅检查值是否由用户设置相比,这看起来有点笨拙。

9 个答案:

答案 0 :(得分:100)

我认为如果没有提供可选参数(用--指定),则初始化为None。因此,您可以使用is not None进行测试。请尝试以下示例:

import argparse as ap

def main():
    parser = ap.ArgumentParser(description="My Script")
    parser.add_argument("--myArg")
    args, leftovers = parser.parse_known_args()

    if args.myArg is not None:
        print "myArg has been set (value is %s)" % args.myArg

答案 1 :(得分:27)

正如@Honza所说,is None是一个很好的考验。它是默认的default,用户无法为您提供与其重复的字符串。

您可以指定另一个default='mydefaultvalue,然后对其进行测试。但是如果用户指定了该字符串呢?这是否算作设置?

您也可以指定default=argparse.SUPPRESS。然后,如果用户不使用该参数,它将不会出现在args命名空间中。但测试可能会更复杂:

args.foo # raises an AttributeError
hasattr(args, 'foo')  # returns False
getattr(args, 'foo', 'other') # returns 'other'

parser在内部保留seen_actions列表,并将其用于“必需”和“互相排斥”测试。但是parse_args以外的人无法使用它。

答案 2 :(得分:8)

我认为使用选项default=argparse.SUPPRESS最有意义。然后,不是检查参数是否为not None,而是检查参数是否为in生成的命名空间。

实施例

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--foo", default=argparse.SUPPRESS)
ns = parser.parse_args()

print("Parsed arguments: {}".format(ns))
print("foo in namespace?: {}".format("foo" in ns))

用法:

$ python argparse_test.py --foo 1
Parsed arguments: Namespace(foo='1')
foo in namespace?: True
不提供参数:
$ python argparse_test.py
Parsed arguments: Namespace()
foo in namespace?: False

答案 3 :(得分:6)

您可以使用store_truestore_false参数操作选项检查可选的传递标记:

import argparse

argparser = argparse.ArgumentParser()
argparser.add_argument('-flag', dest='flag_exists', action='store_true')

print argparser.parse_args([])
# Namespace(flag_exists=False)
print argparser.parse_args(['-flag'])
# Namespace(flag_exists=True)

这样,您就不必担心按条件is not None进行检查。您只需检查TrueFalse即可。在文档here

中详细了解这些选项

答案 4 :(得分:5)

如果你的论点是位置(即它没有" - "或者" - "前缀,只是参数,通常是文件名)然后您可以使用the nargs parameter来执行此操作:

parser = argparse.ArgumentParser(description='Foo is a program that does things')
parser.add_argument('filename', nargs='?')
args = parser.parse_args()

if args.filename is not None:
    print('The file name is {}'.format(args.filename))
else:
    print('Oh well ; No args, no problems')

答案 5 :(得分:0)

为了解决@kcpr对@Honza Osobne的(当前接受的)答案的评论

不幸的是它不起作用,然后参数得到了它的默认值 定义。

首先可以通过将参数与提供Namespace选项的default=argparse.SUPPRESS对象abd进行比较来检查是否提供了参数(请参阅@hpaulj和@Erasmus Cedernaes的答案以及此python3 doc),如果尚未提供,则将其设置为默认值。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--infile', default=argparse.SUPPRESS)
args = parser.parse_args()
if 'infile' in args: 
    # the argument is in the namespace, it's been provided by the user
    # set it to what has been provided
    theinfile = args.infile
    print('argument \'--infile\' was given, set to {}'.format(theinfile))
else:
    # the argument isn't in the namespace
    # set it to a default value
    theinfile = 'your_default.txt'
    print('argument \'--infile\' was not given, set to default {}'.format(theinfile))

用法

$ python3 testargparse_so.py
argument '--infile' was not given, set to default your_default.txt

$ python3 testargparse_so.py --infile user_file.txt
argument '--infile' was given, set to user_file.txt

答案 6 :(得分:0)

自定义操作可以解决此问题。我发现它并不那么复杂。

is_set = set() #global set reference
class IsStored(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        is_set.add(self.dest) # save to global reference
        setattr(namespace, self.dest + '_set', True) # or you may inject directly to namespace
        setattr(namespace, self.dest, values) # implementation of store_action
        # You cannot inject directly to self.dest until you have a custom class


parser.add_argument("--myarg", type=int, default=1, action=IsStored)
params = parser.parse_args()
print(params.myarg, 'myarg' in is_set)
print(hasattr(params, 'myarg_set'))

答案 7 :(得分:0)

这里有一个稍微不同的方法:
假设您知道参数名称,那么您可以执行以下操作:

import sys

def is_set(arg_name):
    if arg_name in sys.argv:
        return True 
    return False

这样你就不需要改变你的参数解析器,仍然可以添加你的自定义逻辑。

答案 8 :(得分:-1)

非常简单,在通过“ args = parser.parse_args()”定义args变量后,它也包含args子集变量的所有数据。要检查是否已设置变量或是否假设使用了'action =“ store_true” ...

public ref class COpenGL : public System::Windows::Forms::NativeWindow
{

   System::Windows::Forms::TextBox^ messageLog;

   public:
   
   COpenGL( System::Windows::Forms::TextBox^ messageLog,
       System::Windows::Forms::SplitterPanel^ parentForm, 
       GLsizei iWidth, GLsizei iHeight)
    {
        this->messageLog=messageLog;
        // ...
    }

    void set_text()
    {
       messageLog->Text = "some text"; 
    }
}