Argparse value for optional positional argument











up vote
1
down vote

favorite












I am trying to create an argparse optional argument that may -OR- may not have an associated input value. I want the following behavior:

1. argument not specified, value=None

2. argument specified with a value, value=user_input

3. argument specified without a value, value=derived from a positional value



The first 2 are easy. It's the third one I can't figure out. I found 2 posts that do something similar:
python argparse optional positional argument with detectable switch

This one sets the default value to a constant for an optional argument without a value.
Argparse optional positional arguments?

This topic is close, but not quite what I need either (he derives the default value from a system call):

I want mine to be a determined from an positional value.



Simple example code I created:



parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')


When I set the input and print:



args = parser.parse_args('my.h5 -c my_file.csv --pnf'.split())
print ('Input = %s' % args.input)
print ('CSV file = %s' % args.csv)
print ('PNF file = %s' % args.pnf)


I get:



Input = my.h5
CSV file = my_file.csv
PNF file = None


If I modify my input to:



args = parser.parse_args('my.h5 -c'.split())


The resulting output is:



Input = my.h5
CSV file = None
PNF file = None


When Value = None, I can't tell if the optional argument was not defined, or was defined but without a value. In the second case, I want to derive the CSV File name from the positional argument (in this example the derived name would be my.csv). I want to do the same when --pnf is defined (where default PNF would be my.pnf for above). Is there a way to do this?










share|improve this question






















  • Use const='foobar' as described in the link. After parsing conditionally replace 'foobar' with args.input.
    – hpaulj
    Nov 9 at 16:10

















up vote
1
down vote

favorite












I am trying to create an argparse optional argument that may -OR- may not have an associated input value. I want the following behavior:

1. argument not specified, value=None

2. argument specified with a value, value=user_input

3. argument specified without a value, value=derived from a positional value



The first 2 are easy. It's the third one I can't figure out. I found 2 posts that do something similar:
python argparse optional positional argument with detectable switch

This one sets the default value to a constant for an optional argument without a value.
Argparse optional positional arguments?

This topic is close, but not quite what I need either (he derives the default value from a system call):

I want mine to be a determined from an positional value.



Simple example code I created:



parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')


When I set the input and print:



args = parser.parse_args('my.h5 -c my_file.csv --pnf'.split())
print ('Input = %s' % args.input)
print ('CSV file = %s' % args.csv)
print ('PNF file = %s' % args.pnf)


I get:



Input = my.h5
CSV file = my_file.csv
PNF file = None


If I modify my input to:



args = parser.parse_args('my.h5 -c'.split())


The resulting output is:



Input = my.h5
CSV file = None
PNF file = None


When Value = None, I can't tell if the optional argument was not defined, or was defined but without a value. In the second case, I want to derive the CSV File name from the positional argument (in this example the derived name would be my.csv). I want to do the same when --pnf is defined (where default PNF would be my.pnf for above). Is there a way to do this?










share|improve this question






















  • Use const='foobar' as described in the link. After parsing conditionally replace 'foobar' with args.input.
    – hpaulj
    Nov 9 at 16:10















up vote
1
down vote

favorite









up vote
1
down vote

favorite











I am trying to create an argparse optional argument that may -OR- may not have an associated input value. I want the following behavior:

1. argument not specified, value=None

2. argument specified with a value, value=user_input

3. argument specified without a value, value=derived from a positional value



The first 2 are easy. It's the third one I can't figure out. I found 2 posts that do something similar:
python argparse optional positional argument with detectable switch

This one sets the default value to a constant for an optional argument without a value.
Argparse optional positional arguments?

This topic is close, but not quite what I need either (he derives the default value from a system call):

I want mine to be a determined from an positional value.



Simple example code I created:



parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')


When I set the input and print:



args = parser.parse_args('my.h5 -c my_file.csv --pnf'.split())
print ('Input = %s' % args.input)
print ('CSV file = %s' % args.csv)
print ('PNF file = %s' % args.pnf)


I get:



Input = my.h5
CSV file = my_file.csv
PNF file = None


If I modify my input to:



args = parser.parse_args('my.h5 -c'.split())


The resulting output is:



Input = my.h5
CSV file = None
PNF file = None


When Value = None, I can't tell if the optional argument was not defined, or was defined but without a value. In the second case, I want to derive the CSV File name from the positional argument (in this example the derived name would be my.csv). I want to do the same when --pnf is defined (where default PNF would be my.pnf for above). Is there a way to do this?










share|improve this question













I am trying to create an argparse optional argument that may -OR- may not have an associated input value. I want the following behavior:

1. argument not specified, value=None

2. argument specified with a value, value=user_input

3. argument specified without a value, value=derived from a positional value



The first 2 are easy. It's the third one I can't figure out. I found 2 posts that do something similar:
python argparse optional positional argument with detectable switch

This one sets the default value to a constant for an optional argument without a value.
Argparse optional positional arguments?

This topic is close, but not quite what I need either (he derives the default value from a system call):

I want mine to be a determined from an positional value.



Simple example code I created:



parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')


When I set the input and print:



args = parser.parse_args('my.h5 -c my_file.csv --pnf'.split())
print ('Input = %s' % args.input)
print ('CSV file = %s' % args.csv)
print ('PNF file = %s' % args.pnf)


I get:



Input = my.h5
CSV file = my_file.csv
PNF file = None


If I modify my input to:



args = parser.parse_args('my.h5 -c'.split())


The resulting output is:



Input = my.h5
CSV file = None
PNF file = None


When Value = None, I can't tell if the optional argument was not defined, or was defined but without a value. In the second case, I want to derive the CSV File name from the positional argument (in this example the derived name would be my.csv). I want to do the same when --pnf is defined (where default PNF would be my.pnf for above). Is there a way to do this?







python argparse






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 9 at 15:29









user10462884

458




458












  • Use const='foobar' as described in the link. After parsing conditionally replace 'foobar' with args.input.
    – hpaulj
    Nov 9 at 16:10




















  • Use const='foobar' as described in the link. After parsing conditionally replace 'foobar' with args.input.
    – hpaulj
    Nov 9 at 16:10


















Use const='foobar' as described in the link. After parsing conditionally replace 'foobar' with args.input.
– hpaulj
Nov 9 at 16:10






Use const='foobar' as described in the link. After parsing conditionally replace 'foobar' with args.input.
– hpaulj
Nov 9 at 16:10














4 Answers
4






active

oldest

votes

















up vote
2
down vote



accepted











I can't tell if the optional argument was not defined, or was defined but without a value




If you create your parser like this:



parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)


Now it is possible to distinguish between the three cases.




  • If -c val was passed, it will be present in args with value "val".

  • If -c was passed without value, it will be present in args with value None.

  • If -c was omitted entirely, it won't be present in args.


The same goes for -p.






share|improve this answer























  • Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
    – user10462884
    Nov 9 at 18:37


















up vote
0
down vote













Making use of the const parameter:



import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?', const='foobar')
parser.add_argument('-p', '--pnf', nargs='?', const='foobar')

args = parser.parse_args()
print(args)

if args.csv and args.csv=='foobar':
args.csv = args.input

args.pnf = args.input if (args.pnf and args.pnf=='foobar') else args.pnf

print(args)


Your two sample inputs:



0933:~/mypy$ python3 stack53228663.py my.h5 -c my_file.csv --pnf
Namespace(csv='my_file.csv', input='my.h5', pnf='foobar')
Namespace(csv='my_file.csv', input='my.h5', pnf='my.h5')

0933:~/mypy$ python3 stack53228663.py my.h5 -c
Namespace(csv='foobar', input='my.h5', pnf=None)
Namespace(csv='my.h5', input='my.h5', pnf=None)





share|improve this answer





















  • Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
    – user10462884
    Nov 9 at 18:47










  • You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
    – hpaulj
    Nov 9 at 19:29










  • "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
    – user10462884
    Nov 9 at 20:36






  • 1




    That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
    – hpaulj
    Nov 9 at 20:41












  • Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
    – user10462884
    Nov 9 at 21:25


















up vote
0
down vote













For completeness (and future reference), I am posting the modified code required to get arguments when using argument_default=argparse.SUPPRESS. See below:



parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')
args = parser.parse_args('my.h5 -c my_file --pnf'.split())
for d_key, d_val in vars(args).items() :
print (d_key, d_val)


Results in this output:



input my.h5
csv my_file
pnf None


For the second set of inputs



args = parser.parse_args('my.h5 -c'.split())
print(vars(args))
for d_key, d_val in vars(args).items() :
print (d_key, d_val)


Output looks like this:



input my.h5
csv None





share|improve this answer




























    up vote
    0
    down vote













    This shows the logic I implemented using default=False, const=True, based on earlier comments from @hpaulj.



    parser = argparse.ArgumentParser()
    parser.add_argument('input')
    parser.add_argument('-c', '--csv', nargs='?', default=False, const=True)
    parser.add_argument('-p', '--pnf', nargs='?', default=False, const=True)
    args = parser.parse_args('my.h5 -c'.split())
    print(vars(args))
    HDF5_FILE = args.input
    if isinstance(args.csv, str) :
    CSV_FILE = args.csv
    elif args.csv :
    CSV_FILE=HDF5_FILE[:-3] + '_v3_stress.csv'
    else :
    CSV_FILE = ''
    # repeat above logic for args.pnf
    print ('input=', HDF5_FILE, ', csv=', CSV_FILE, ' pnf=', PNF_FILE )


    Resulting output looks like this:



    {'input': 'my.h5', 'csv': True, 'pnf': False}
    hdf5= my.h5 , csv= my_v3_stress.csv pnf=


    Modified 'parse_args()' and resulting output:



    args = parser.parse_args('my.h5 -c my_file.csv -p'.split())


    Gives:



    {'input': 'my.h5', 'csv': 'my_file.csv', 'pnf': True}
    hdf5= my.h5 , csv= my_file.csv pnf= my_v3_stress.nrf


    If I had a lot of variables to check, I would move the if/elif/else logic to a def that returns the desired value.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228663%2fargparse-value-for-optional-positional-argument%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote



      accepted











      I can't tell if the optional argument was not defined, or was defined but without a value




      If you create your parser like this:



      parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)


      Now it is possible to distinguish between the three cases.




      • If -c val was passed, it will be present in args with value "val".

      • If -c was passed without value, it will be present in args with value None.

      • If -c was omitted entirely, it won't be present in args.


      The same goes for -p.






      share|improve this answer























      • Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
        – user10462884
        Nov 9 at 18:37















      up vote
      2
      down vote



      accepted











      I can't tell if the optional argument was not defined, or was defined but without a value




      If you create your parser like this:



      parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)


      Now it is possible to distinguish between the three cases.




      • If -c val was passed, it will be present in args with value "val".

      • If -c was passed without value, it will be present in args with value None.

      • If -c was omitted entirely, it won't be present in args.


      The same goes for -p.






      share|improve this answer























      • Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
        – user10462884
        Nov 9 at 18:37













      up vote
      2
      down vote



      accepted







      up vote
      2
      down vote



      accepted







      I can't tell if the optional argument was not defined, or was defined but without a value




      If you create your parser like this:



      parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)


      Now it is possible to distinguish between the three cases.




      • If -c val was passed, it will be present in args with value "val".

      • If -c was passed without value, it will be present in args with value None.

      • If -c was omitted entirely, it won't be present in args.


      The same goes for -p.






      share|improve this answer















      I can't tell if the optional argument was not defined, or was defined but without a value




      If you create your parser like this:



      parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)


      Now it is possible to distinguish between the three cases.




      • If -c val was passed, it will be present in args with value "val".

      • If -c was passed without value, it will be present in args with value None.

      • If -c was omitted entirely, it won't be present in args.


      The same goes for -p.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 9 at 15:42

























      answered Nov 9 at 15:37









      wim

      154k47293424




      154k47293424












      • Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
        – user10462884
        Nov 9 at 18:37


















      • Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
        – user10462884
        Nov 9 at 18:37
















      Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
      – user10462884
      Nov 9 at 18:37




      Thanks, works like a champ (with a small change to get the arguments and values) I saw that in the python.org docs, but couldn't decipher how it worked. Thanks!
      – user10462884
      Nov 9 at 18:37












      up vote
      0
      down vote













      Making use of the const parameter:



      import argparse
      parser = argparse.ArgumentParser()
      parser.add_argument('input')
      parser.add_argument('-c', '--csv', nargs='?', const='foobar')
      parser.add_argument('-p', '--pnf', nargs='?', const='foobar')

      args = parser.parse_args()
      print(args)

      if args.csv and args.csv=='foobar':
      args.csv = args.input

      args.pnf = args.input if (args.pnf and args.pnf=='foobar') else args.pnf

      print(args)


      Your two sample inputs:



      0933:~/mypy$ python3 stack53228663.py my.h5 -c my_file.csv --pnf
      Namespace(csv='my_file.csv', input='my.h5', pnf='foobar')
      Namespace(csv='my_file.csv', input='my.h5', pnf='my.h5')

      0933:~/mypy$ python3 stack53228663.py my.h5 -c
      Namespace(csv='foobar', input='my.h5', pnf=None)
      Namespace(csv='my.h5', input='my.h5', pnf=None)





      share|improve this answer





















      • Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
        – user10462884
        Nov 9 at 18:47










      • You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
        – hpaulj
        Nov 9 at 19:29










      • "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
        – user10462884
        Nov 9 at 20:36






      • 1




        That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
        – hpaulj
        Nov 9 at 20:41












      • Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
        – user10462884
        Nov 9 at 21:25















      up vote
      0
      down vote













      Making use of the const parameter:



      import argparse
      parser = argparse.ArgumentParser()
      parser.add_argument('input')
      parser.add_argument('-c', '--csv', nargs='?', const='foobar')
      parser.add_argument('-p', '--pnf', nargs='?', const='foobar')

      args = parser.parse_args()
      print(args)

      if args.csv and args.csv=='foobar':
      args.csv = args.input

      args.pnf = args.input if (args.pnf and args.pnf=='foobar') else args.pnf

      print(args)


      Your two sample inputs:



      0933:~/mypy$ python3 stack53228663.py my.h5 -c my_file.csv --pnf
      Namespace(csv='my_file.csv', input='my.h5', pnf='foobar')
      Namespace(csv='my_file.csv', input='my.h5', pnf='my.h5')

      0933:~/mypy$ python3 stack53228663.py my.h5 -c
      Namespace(csv='foobar', input='my.h5', pnf=None)
      Namespace(csv='my.h5', input='my.h5', pnf=None)





      share|improve this answer





















      • Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
        – user10462884
        Nov 9 at 18:47










      • You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
        – hpaulj
        Nov 9 at 19:29










      • "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
        – user10462884
        Nov 9 at 20:36






      • 1




        That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
        – hpaulj
        Nov 9 at 20:41












      • Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
        – user10462884
        Nov 9 at 21:25













      up vote
      0
      down vote










      up vote
      0
      down vote









      Making use of the const parameter:



      import argparse
      parser = argparse.ArgumentParser()
      parser.add_argument('input')
      parser.add_argument('-c', '--csv', nargs='?', const='foobar')
      parser.add_argument('-p', '--pnf', nargs='?', const='foobar')

      args = parser.parse_args()
      print(args)

      if args.csv and args.csv=='foobar':
      args.csv = args.input

      args.pnf = args.input if (args.pnf and args.pnf=='foobar') else args.pnf

      print(args)


      Your two sample inputs:



      0933:~/mypy$ python3 stack53228663.py my.h5 -c my_file.csv --pnf
      Namespace(csv='my_file.csv', input='my.h5', pnf='foobar')
      Namespace(csv='my_file.csv', input='my.h5', pnf='my.h5')

      0933:~/mypy$ python3 stack53228663.py my.h5 -c
      Namespace(csv='foobar', input='my.h5', pnf=None)
      Namespace(csv='my.h5', input='my.h5', pnf=None)





      share|improve this answer












      Making use of the const parameter:



      import argparse
      parser = argparse.ArgumentParser()
      parser.add_argument('input')
      parser.add_argument('-c', '--csv', nargs='?', const='foobar')
      parser.add_argument('-p', '--pnf', nargs='?', const='foobar')

      args = parser.parse_args()
      print(args)

      if args.csv and args.csv=='foobar':
      args.csv = args.input

      args.pnf = args.input if (args.pnf and args.pnf=='foobar') else args.pnf

      print(args)


      Your two sample inputs:



      0933:~/mypy$ python3 stack53228663.py my.h5 -c my_file.csv --pnf
      Namespace(csv='my_file.csv', input='my.h5', pnf='foobar')
      Namespace(csv='my_file.csv', input='my.h5', pnf='my.h5')

      0933:~/mypy$ python3 stack53228663.py my.h5 -c
      Namespace(csv='foobar', input='my.h5', pnf=None)
      Namespace(csv='my.h5', input='my.h5', pnf=None)






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 9 at 17:36









      hpaulj

      108k673138




      108k673138












      • Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
        – user10462884
        Nov 9 at 18:47










      • You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
        – hpaulj
        Nov 9 at 19:29










      • "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
        – user10462884
        Nov 9 at 20:36






      • 1




        That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
        – hpaulj
        Nov 9 at 20:41












      • Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
        – user10462884
        Nov 9 at 21:25


















      • Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
        – user10462884
        Nov 9 at 18:47










      • You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
        – hpaulj
        Nov 9 at 19:29










      • "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
        – user10462884
        Nov 9 at 20:36






      • 1




        That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
        – hpaulj
        Nov 9 at 20:41












      • Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
        – user10462884
        Nov 9 at 21:25
















      Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
      – user10462884
      Nov 9 at 18:47




      Thanks hpaulj, that's another approach. Not sure which is more "pythonic". Personally, I like argparse.SUPPRESS b/c it's more readable (to me).
      – user10462884
      Nov 9 at 18:47












      You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
      – hpaulj
      Nov 9 at 19:29




      You can also set this default in the add_argument command: default=argparse.SUPPRESS. In my version, default is None. And your 'const' is effectively None. Which is easier to test for, a None value or a missing attribute or key? Just as long as you are clear about the alternatives it really doesn't matter which you use.
      – hpaulj
      Nov 9 at 19:29












      "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
      – user10462884
      Nov 9 at 20:36




      "Which is easier: test a value or test for a missing key"? Yes, exactly, either way I'm writing some code to test and set the value. :-) In a perfect world, I'd like an action that combines action='store' and action='store_true'. When the optional argument is not entered, it's returned as 'False'. When it's entered without a value, it's returned as 'True'. And, when entered with a value, it's returned with that value -- or maybe returned as a tuple with: (argname, True/False, value).
      – user10462884
      Nov 9 at 20:36




      1




      1




      That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
      – hpaulj
      Nov 9 at 20:41






      That's easy - nargs='?', default=False, const=True. store_true is just store_const with those default and const values (and nargs=0).
      – hpaulj
      Nov 9 at 20:41














      Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
      – user10462884
      Nov 9 at 21:25




      Yeah, I like that one. Didn't realize I could use default= and const= together. Good to know! Test logic is very clean and readable. You should post as an answer so I can +1. Thanks!
      – user10462884
      Nov 9 at 21:25










      up vote
      0
      down vote













      For completeness (and future reference), I am posting the modified code required to get arguments when using argument_default=argparse.SUPPRESS. See below:



      parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
      parser.add_argument('input')
      parser.add_argument('-c', '--csv', nargs='?')
      parser.add_argument('-p', '--pnf', nargs='?')
      args = parser.parse_args('my.h5 -c my_file --pnf'.split())
      for d_key, d_val in vars(args).items() :
      print (d_key, d_val)


      Results in this output:



      input my.h5
      csv my_file
      pnf None


      For the second set of inputs



      args = parser.parse_args('my.h5 -c'.split())
      print(vars(args))
      for d_key, d_val in vars(args).items() :
      print (d_key, d_val)


      Output looks like this:



      input my.h5
      csv None





      share|improve this answer

























        up vote
        0
        down vote













        For completeness (and future reference), I am posting the modified code required to get arguments when using argument_default=argparse.SUPPRESS. See below:



        parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
        parser.add_argument('input')
        parser.add_argument('-c', '--csv', nargs='?')
        parser.add_argument('-p', '--pnf', nargs='?')
        args = parser.parse_args('my.h5 -c my_file --pnf'.split())
        for d_key, d_val in vars(args).items() :
        print (d_key, d_val)


        Results in this output:



        input my.h5
        csv my_file
        pnf None


        For the second set of inputs



        args = parser.parse_args('my.h5 -c'.split())
        print(vars(args))
        for d_key, d_val in vars(args).items() :
        print (d_key, d_val)


        Output looks like this:



        input my.h5
        csv None





        share|improve this answer























          up vote
          0
          down vote










          up vote
          0
          down vote









          For completeness (and future reference), I am posting the modified code required to get arguments when using argument_default=argparse.SUPPRESS. See below:



          parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
          parser.add_argument('input')
          parser.add_argument('-c', '--csv', nargs='?')
          parser.add_argument('-p', '--pnf', nargs='?')
          args = parser.parse_args('my.h5 -c my_file --pnf'.split())
          for d_key, d_val in vars(args).items() :
          print (d_key, d_val)


          Results in this output:



          input my.h5
          csv my_file
          pnf None


          For the second set of inputs



          args = parser.parse_args('my.h5 -c'.split())
          print(vars(args))
          for d_key, d_val in vars(args).items() :
          print (d_key, d_val)


          Output looks like this:



          input my.h5
          csv None





          share|improve this answer












          For completeness (and future reference), I am posting the modified code required to get arguments when using argument_default=argparse.SUPPRESS. See below:



          parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
          parser.add_argument('input')
          parser.add_argument('-c', '--csv', nargs='?')
          parser.add_argument('-p', '--pnf', nargs='?')
          args = parser.parse_args('my.h5 -c my_file --pnf'.split())
          for d_key, d_val in vars(args).items() :
          print (d_key, d_val)


          Results in this output:



          input my.h5
          csv my_file
          pnf None


          For the second set of inputs



          args = parser.parse_args('my.h5 -c'.split())
          print(vars(args))
          for d_key, d_val in vars(args).items() :
          print (d_key, d_val)


          Output looks like this:



          input my.h5
          csv None






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 9 at 18:42









          user10462884

          458




          458






















              up vote
              0
              down vote













              This shows the logic I implemented using default=False, const=True, based on earlier comments from @hpaulj.



              parser = argparse.ArgumentParser()
              parser.add_argument('input')
              parser.add_argument('-c', '--csv', nargs='?', default=False, const=True)
              parser.add_argument('-p', '--pnf', nargs='?', default=False, const=True)
              args = parser.parse_args('my.h5 -c'.split())
              print(vars(args))
              HDF5_FILE = args.input
              if isinstance(args.csv, str) :
              CSV_FILE = args.csv
              elif args.csv :
              CSV_FILE=HDF5_FILE[:-3] + '_v3_stress.csv'
              else :
              CSV_FILE = ''
              # repeat above logic for args.pnf
              print ('input=', HDF5_FILE, ', csv=', CSV_FILE, ' pnf=', PNF_FILE )


              Resulting output looks like this:



              {'input': 'my.h5', 'csv': True, 'pnf': False}
              hdf5= my.h5 , csv= my_v3_stress.csv pnf=


              Modified 'parse_args()' and resulting output:



              args = parser.parse_args('my.h5 -c my_file.csv -p'.split())


              Gives:



              {'input': 'my.h5', 'csv': 'my_file.csv', 'pnf': True}
              hdf5= my.h5 , csv= my_file.csv pnf= my_v3_stress.nrf


              If I had a lot of variables to check, I would move the if/elif/else logic to a def that returns the desired value.






              share|improve this answer



























                up vote
                0
                down vote













                This shows the logic I implemented using default=False, const=True, based on earlier comments from @hpaulj.



                parser = argparse.ArgumentParser()
                parser.add_argument('input')
                parser.add_argument('-c', '--csv', nargs='?', default=False, const=True)
                parser.add_argument('-p', '--pnf', nargs='?', default=False, const=True)
                args = parser.parse_args('my.h5 -c'.split())
                print(vars(args))
                HDF5_FILE = args.input
                if isinstance(args.csv, str) :
                CSV_FILE = args.csv
                elif args.csv :
                CSV_FILE=HDF5_FILE[:-3] + '_v3_stress.csv'
                else :
                CSV_FILE = ''
                # repeat above logic for args.pnf
                print ('input=', HDF5_FILE, ', csv=', CSV_FILE, ' pnf=', PNF_FILE )


                Resulting output looks like this:



                {'input': 'my.h5', 'csv': True, 'pnf': False}
                hdf5= my.h5 , csv= my_v3_stress.csv pnf=


                Modified 'parse_args()' and resulting output:



                args = parser.parse_args('my.h5 -c my_file.csv -p'.split())


                Gives:



                {'input': 'my.h5', 'csv': 'my_file.csv', 'pnf': True}
                hdf5= my.h5 , csv= my_file.csv pnf= my_v3_stress.nrf


                If I had a lot of variables to check, I would move the if/elif/else logic to a def that returns the desired value.






                share|improve this answer

























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  This shows the logic I implemented using default=False, const=True, based on earlier comments from @hpaulj.



                  parser = argparse.ArgumentParser()
                  parser.add_argument('input')
                  parser.add_argument('-c', '--csv', nargs='?', default=False, const=True)
                  parser.add_argument('-p', '--pnf', nargs='?', default=False, const=True)
                  args = parser.parse_args('my.h5 -c'.split())
                  print(vars(args))
                  HDF5_FILE = args.input
                  if isinstance(args.csv, str) :
                  CSV_FILE = args.csv
                  elif args.csv :
                  CSV_FILE=HDF5_FILE[:-3] + '_v3_stress.csv'
                  else :
                  CSV_FILE = ''
                  # repeat above logic for args.pnf
                  print ('input=', HDF5_FILE, ', csv=', CSV_FILE, ' pnf=', PNF_FILE )


                  Resulting output looks like this:



                  {'input': 'my.h5', 'csv': True, 'pnf': False}
                  hdf5= my.h5 , csv= my_v3_stress.csv pnf=


                  Modified 'parse_args()' and resulting output:



                  args = parser.parse_args('my.h5 -c my_file.csv -p'.split())


                  Gives:



                  {'input': 'my.h5', 'csv': 'my_file.csv', 'pnf': True}
                  hdf5= my.h5 , csv= my_file.csv pnf= my_v3_stress.nrf


                  If I had a lot of variables to check, I would move the if/elif/else logic to a def that returns the desired value.






                  share|improve this answer














                  This shows the logic I implemented using default=False, const=True, based on earlier comments from @hpaulj.



                  parser = argparse.ArgumentParser()
                  parser.add_argument('input')
                  parser.add_argument('-c', '--csv', nargs='?', default=False, const=True)
                  parser.add_argument('-p', '--pnf', nargs='?', default=False, const=True)
                  args = parser.parse_args('my.h5 -c'.split())
                  print(vars(args))
                  HDF5_FILE = args.input
                  if isinstance(args.csv, str) :
                  CSV_FILE = args.csv
                  elif args.csv :
                  CSV_FILE=HDF5_FILE[:-3] + '_v3_stress.csv'
                  else :
                  CSV_FILE = ''
                  # repeat above logic for args.pnf
                  print ('input=', HDF5_FILE, ', csv=', CSV_FILE, ' pnf=', PNF_FILE )


                  Resulting output looks like this:



                  {'input': 'my.h5', 'csv': True, 'pnf': False}
                  hdf5= my.h5 , csv= my_v3_stress.csv pnf=


                  Modified 'parse_args()' and resulting output:



                  args = parser.parse_args('my.h5 -c my_file.csv -p'.split())


                  Gives:



                  {'input': 'my.h5', 'csv': 'my_file.csv', 'pnf': True}
                  hdf5= my.h5 , csv= my_file.csv pnf= my_v3_stress.nrf


                  If I had a lot of variables to check, I would move the if/elif/else logic to a def that returns the desired value.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 11 at 22:04

























                  answered Nov 10 at 19:05









                  user10462884

                  458




                  458






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228663%2fargparse-value-for-optional-positional-argument%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Schultheiß

                      Verwaltungsgliederung Dänemarks

                      Liste der Kulturdenkmale in Wilsdruff