argparse - Define custom actions or types with additional arguments
I'm developing a toolbox containing several python scripts. For several of them some arguments may be numeric values. Depending of the script some may require a value v to be between -1 and 1, or 0 and 1 or 1 and 10 or ... An example could be a page width from an output diagram which should be always positive.
I can check all the time if v is in the required range. I could also for each of these range define an Action or a type using argparse. An example is given using a new type:
def positive_num(a_value):
"""Check a numeric positive."""
if not a_value > 0:
raise argparse.ArgumentTypeError("Should be positive.")
return a_value
And add it later to the parser:
parser_grp.add_argument('-pw', '--page-width',
help='Output pdf file width (e.g. 7 inches).',
type=positive_num,
default=None,
required=False)
Now, if the value is a correlation coefficient (or anything in a range) would it be possible using action or types to write something more general using:
def ranged_num(a_value, lowest=-1, highest=1):
"""Check a numeric is in expected range."""
if not (a_value >= lowest and a_value <= highest):
raise argparse.ArgumentTypeError("Not in range.")
return a_value
That could later be added like:
parser_grp.add_argument('-c', '--correlation',
help='A value for the correlation coefficient',
type=ranged_num(-1,1),
default=None,
required=False)
I have tried in several ways but whithout success.
Thank you
python argparse
add a comment |
I'm developing a toolbox containing several python scripts. For several of them some arguments may be numeric values. Depending of the script some may require a value v to be between -1 and 1, or 0 and 1 or 1 and 10 or ... An example could be a page width from an output diagram which should be always positive.
I can check all the time if v is in the required range. I could also for each of these range define an Action or a type using argparse. An example is given using a new type:
def positive_num(a_value):
"""Check a numeric positive."""
if not a_value > 0:
raise argparse.ArgumentTypeError("Should be positive.")
return a_value
And add it later to the parser:
parser_grp.add_argument('-pw', '--page-width',
help='Output pdf file width (e.g. 7 inches).',
type=positive_num,
default=None,
required=False)
Now, if the value is a correlation coefficient (or anything in a range) would it be possible using action or types to write something more general using:
def ranged_num(a_value, lowest=-1, highest=1):
"""Check a numeric is in expected range."""
if not (a_value >= lowest and a_value <= highest):
raise argparse.ArgumentTypeError("Not in range.")
return a_value
That could later be added like:
parser_grp.add_argument('-c', '--correlation',
help='A value for the correlation coefficient',
type=ranged_num(-1,1),
default=None,
required=False)
I have tried in several ways but whithout success.
Thank you
python argparse
You need a higher-order function to do this, a function that returns a function.type
needs to be a function that accepts a single (note: string) argument, so that's whatranged_num(-1, 1)
needs to return.
– jonrsharpe
Nov 23 '18 at 11:28
Yes... That's it. I will dig into that.
– user451460
Nov 23 '18 at 11:32
The question is how will I pass the range (-1,1) to this higher-order function since the normal way is to pass a function definition and not a function call to the type argument of add_argument() method. I recall that I don't want to write a particular function for each range.
– user451460
Nov 23 '18 at 11:42
That's the point of a higher-order function; the function that returns thetype
function can also take parameters. You would writetype=ranged_num(-1, 1)
, and that function would return an appropriately-configures function that accepts the string argument.
– jonrsharpe
Nov 23 '18 at 11:44
functools.partial
can be used to bind thelow
andhigh
ofranged_num
.
– hpaulj
Nov 23 '18 at 16:12
add a comment |
I'm developing a toolbox containing several python scripts. For several of them some arguments may be numeric values. Depending of the script some may require a value v to be between -1 and 1, or 0 and 1 or 1 and 10 or ... An example could be a page width from an output diagram which should be always positive.
I can check all the time if v is in the required range. I could also for each of these range define an Action or a type using argparse. An example is given using a new type:
def positive_num(a_value):
"""Check a numeric positive."""
if not a_value > 0:
raise argparse.ArgumentTypeError("Should be positive.")
return a_value
And add it later to the parser:
parser_grp.add_argument('-pw', '--page-width',
help='Output pdf file width (e.g. 7 inches).',
type=positive_num,
default=None,
required=False)
Now, if the value is a correlation coefficient (or anything in a range) would it be possible using action or types to write something more general using:
def ranged_num(a_value, lowest=-1, highest=1):
"""Check a numeric is in expected range."""
if not (a_value >= lowest and a_value <= highest):
raise argparse.ArgumentTypeError("Not in range.")
return a_value
That could later be added like:
parser_grp.add_argument('-c', '--correlation',
help='A value for the correlation coefficient',
type=ranged_num(-1,1),
default=None,
required=False)
I have tried in several ways but whithout success.
Thank you
python argparse
I'm developing a toolbox containing several python scripts. For several of them some arguments may be numeric values. Depending of the script some may require a value v to be between -1 and 1, or 0 and 1 or 1 and 10 or ... An example could be a page width from an output diagram which should be always positive.
I can check all the time if v is in the required range. I could also for each of these range define an Action or a type using argparse. An example is given using a new type:
def positive_num(a_value):
"""Check a numeric positive."""
if not a_value > 0:
raise argparse.ArgumentTypeError("Should be positive.")
return a_value
And add it later to the parser:
parser_grp.add_argument('-pw', '--page-width',
help='Output pdf file width (e.g. 7 inches).',
type=positive_num,
default=None,
required=False)
Now, if the value is a correlation coefficient (or anything in a range) would it be possible using action or types to write something more general using:
def ranged_num(a_value, lowest=-1, highest=1):
"""Check a numeric is in expected range."""
if not (a_value >= lowest and a_value <= highest):
raise argparse.ArgumentTypeError("Not in range.")
return a_value
That could later be added like:
parser_grp.add_argument('-c', '--correlation',
help='A value for the correlation coefficient',
type=ranged_num(-1,1),
default=None,
required=False)
I have tried in several ways but whithout success.
Thank you
python argparse
python argparse
asked Nov 23 '18 at 11:21
user451460
1499
1499
You need a higher-order function to do this, a function that returns a function.type
needs to be a function that accepts a single (note: string) argument, so that's whatranged_num(-1, 1)
needs to return.
– jonrsharpe
Nov 23 '18 at 11:28
Yes... That's it. I will dig into that.
– user451460
Nov 23 '18 at 11:32
The question is how will I pass the range (-1,1) to this higher-order function since the normal way is to pass a function definition and not a function call to the type argument of add_argument() method. I recall that I don't want to write a particular function for each range.
– user451460
Nov 23 '18 at 11:42
That's the point of a higher-order function; the function that returns thetype
function can also take parameters. You would writetype=ranged_num(-1, 1)
, and that function would return an appropriately-configures function that accepts the string argument.
– jonrsharpe
Nov 23 '18 at 11:44
functools.partial
can be used to bind thelow
andhigh
ofranged_num
.
– hpaulj
Nov 23 '18 at 16:12
add a comment |
You need a higher-order function to do this, a function that returns a function.type
needs to be a function that accepts a single (note: string) argument, so that's whatranged_num(-1, 1)
needs to return.
– jonrsharpe
Nov 23 '18 at 11:28
Yes... That's it. I will dig into that.
– user451460
Nov 23 '18 at 11:32
The question is how will I pass the range (-1,1) to this higher-order function since the normal way is to pass a function definition and not a function call to the type argument of add_argument() method. I recall that I don't want to write a particular function for each range.
– user451460
Nov 23 '18 at 11:42
That's the point of a higher-order function; the function that returns thetype
function can also take parameters. You would writetype=ranged_num(-1, 1)
, and that function would return an appropriately-configures function that accepts the string argument.
– jonrsharpe
Nov 23 '18 at 11:44
functools.partial
can be used to bind thelow
andhigh
ofranged_num
.
– hpaulj
Nov 23 '18 at 16:12
You need a higher-order function to do this, a function that returns a function.
type
needs to be a function that accepts a single (note: string) argument, so that's what ranged_num(-1, 1)
needs to return.– jonrsharpe
Nov 23 '18 at 11:28
You need a higher-order function to do this, a function that returns a function.
type
needs to be a function that accepts a single (note: string) argument, so that's what ranged_num(-1, 1)
needs to return.– jonrsharpe
Nov 23 '18 at 11:28
Yes... That's it. I will dig into that.
– user451460
Nov 23 '18 at 11:32
Yes... That's it. I will dig into that.
– user451460
Nov 23 '18 at 11:32
The question is how will I pass the range (-1,1) to this higher-order function since the normal way is to pass a function definition and not a function call to the type argument of add_argument() method. I recall that I don't want to write a particular function for each range.
– user451460
Nov 23 '18 at 11:42
The question is how will I pass the range (-1,1) to this higher-order function since the normal way is to pass a function definition and not a function call to the type argument of add_argument() method. I recall that I don't want to write a particular function for each range.
– user451460
Nov 23 '18 at 11:42
That's the point of a higher-order function; the function that returns the
type
function can also take parameters. You would write type=ranged_num(-1, 1)
, and that function would return an appropriately-configures function that accepts the string argument.– jonrsharpe
Nov 23 '18 at 11:44
That's the point of a higher-order function; the function that returns the
type
function can also take parameters. You would write type=ranged_num(-1, 1)
, and that function would return an appropriately-configures function that accepts the string argument.– jonrsharpe
Nov 23 '18 at 11:44
functools.partial
can be used to bind the low
and high
of ranged_num
.– hpaulj
Nov 23 '18 at 16:12
functools.partial
can be used to bind the low
and high
of ranged_num
.– hpaulj
Nov 23 '18 at 16:12
add a comment |
1 Answer
1
active
oldest
votes
Per the documentation:
type=
can take any callable that takes a single string argument and
returns the converted value
Therefore, to use it like type=ranged_num(-1,1)
, your ranged_num
function must return a function itself. A function that returns a function (or accepts a function as an argument, or both) is often referred to as a "higher-order function".
Here's a minimal example:
def ranged_num(lowest=-1, highest=1):
"""Check a numeric is in expected range."""
def type_func(a_value):
a_value = int(a_value) # or "float"; you could also have error handling here
if not (a_value >= lowest and a_value <= highest): # I'd rewrite this to an "or"
raise argparse.ArgumentTypeError("Not in range.")
return a_value
return type_func
Now ranged_num
creates and returns a function, type_func
, that is responsible for handling the string coming from the command line.
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445769%2fargparse-define-custom-actions-or-types-with-additional-arguments%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Per the documentation:
type=
can take any callable that takes a single string argument and
returns the converted value
Therefore, to use it like type=ranged_num(-1,1)
, your ranged_num
function must return a function itself. A function that returns a function (or accepts a function as an argument, or both) is often referred to as a "higher-order function".
Here's a minimal example:
def ranged_num(lowest=-1, highest=1):
"""Check a numeric is in expected range."""
def type_func(a_value):
a_value = int(a_value) # or "float"; you could also have error handling here
if not (a_value >= lowest and a_value <= highest): # I'd rewrite this to an "or"
raise argparse.ArgumentTypeError("Not in range.")
return a_value
return type_func
Now ranged_num
creates and returns a function, type_func
, that is responsible for handling the string coming from the command line.
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
add a comment |
Per the documentation:
type=
can take any callable that takes a single string argument and
returns the converted value
Therefore, to use it like type=ranged_num(-1,1)
, your ranged_num
function must return a function itself. A function that returns a function (or accepts a function as an argument, or both) is often referred to as a "higher-order function".
Here's a minimal example:
def ranged_num(lowest=-1, highest=1):
"""Check a numeric is in expected range."""
def type_func(a_value):
a_value = int(a_value) # or "float"; you could also have error handling here
if not (a_value >= lowest and a_value <= highest): # I'd rewrite this to an "or"
raise argparse.ArgumentTypeError("Not in range.")
return a_value
return type_func
Now ranged_num
creates and returns a function, type_func
, that is responsible for handling the string coming from the command line.
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
add a comment |
Per the documentation:
type=
can take any callable that takes a single string argument and
returns the converted value
Therefore, to use it like type=ranged_num(-1,1)
, your ranged_num
function must return a function itself. A function that returns a function (or accepts a function as an argument, or both) is often referred to as a "higher-order function".
Here's a minimal example:
def ranged_num(lowest=-1, highest=1):
"""Check a numeric is in expected range."""
def type_func(a_value):
a_value = int(a_value) # or "float"; you could also have error handling here
if not (a_value >= lowest and a_value <= highest): # I'd rewrite this to an "or"
raise argparse.ArgumentTypeError("Not in range.")
return a_value
return type_func
Now ranged_num
creates and returns a function, type_func
, that is responsible for handling the string coming from the command line.
Per the documentation:
type=
can take any callable that takes a single string argument and
returns the converted value
Therefore, to use it like type=ranged_num(-1,1)
, your ranged_num
function must return a function itself. A function that returns a function (or accepts a function as an argument, or both) is often referred to as a "higher-order function".
Here's a minimal example:
def ranged_num(lowest=-1, highest=1):
"""Check a numeric is in expected range."""
def type_func(a_value):
a_value = int(a_value) # or "float"; you could also have error handling here
if not (a_value >= lowest and a_value <= highest): # I'd rewrite this to an "or"
raise argparse.ArgumentTypeError("Not in range.")
return a_value
return type_func
Now ranged_num
creates and returns a function, type_func
, that is responsible for handling the string coming from the command line.
answered Nov 23 '18 at 11:49
jonrsharpe
76.7k11101208
76.7k11101208
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
add a comment |
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
I was on the way.Did not think about the fact that lowest and highest where visible inside type_func... Thanks a lot for this short lesson. Best
– user451460
Nov 23 '18 at 12:16
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
@user451460 no worries; if you want more information on that, it's referred to as a "closure"
– jonrsharpe
Nov 23 '18 at 12:17
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
This is also nicer with a or... Thanks.
– user451460
Nov 23 '18 at 12:22
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445769%2fargparse-define-custom-actions-or-types-with-additional-arguments%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
You need a higher-order function to do this, a function that returns a function.
type
needs to be a function that accepts a single (note: string) argument, so that's whatranged_num(-1, 1)
needs to return.– jonrsharpe
Nov 23 '18 at 11:28
Yes... That's it. I will dig into that.
– user451460
Nov 23 '18 at 11:32
The question is how will I pass the range (-1,1) to this higher-order function since the normal way is to pass a function definition and not a function call to the type argument of add_argument() method. I recall that I don't want to write a particular function for each range.
– user451460
Nov 23 '18 at 11:42
That's the point of a higher-order function; the function that returns the
type
function can also take parameters. You would writetype=ranged_num(-1, 1)
, and that function would return an appropriately-configures function that accepts the string argument.– jonrsharpe
Nov 23 '18 at 11:44
functools.partial
can be used to bind thelow
andhigh
ofranged_num
.– hpaulj
Nov 23 '18 at 16:12