Make functions importable when using argparse
up vote
0
down vote
favorite
I have the following CLI program which adds two numbers:
import argparse
def foo(args):
print('X + Y:', args.x + args.y)
return args.x + args.y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', type=int, default=1)
foo_parser.add_argument('-y', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(args)
Suppose now I want my users to also be able to import foo
and call it directly with arguments x
and y
. I.e. I want foo
to look like this:
def foo(x, y):
print('X + Y:', x + y)
return x + y
How can I adapt args.func(args)
to handle this new foo
?
python argparse
add a comment |
up vote
0
down vote
favorite
I have the following CLI program which adds two numbers:
import argparse
def foo(args):
print('X + Y:', args.x + args.y)
return args.x + args.y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', type=int, default=1)
foo_parser.add_argument('-y', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(args)
Suppose now I want my users to also be able to import foo
and call it directly with arguments x
and y
. I.e. I want foo
to look like this:
def foo(x, y):
print('X + Y:', x + y)
return x + y
How can I adapt args.func(args)
to handle this new foo
?
python argparse
One solution might involve something likeargs.func(*vars(args))
. I'm not sure how to removefunc
fromvars(args)
, though.
– Evidlo
Nov 5 at 4:22
def foo(x=0, y=0):
can be called a variety of ways.foo(1,2)
,foo(x=1, y=2)
,foo(**adict)
,foo(**vars(args))
.
– hpaulj
Nov 5 at 6:02
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have the following CLI program which adds two numbers:
import argparse
def foo(args):
print('X + Y:', args.x + args.y)
return args.x + args.y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', type=int, default=1)
foo_parser.add_argument('-y', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(args)
Suppose now I want my users to also be able to import foo
and call it directly with arguments x
and y
. I.e. I want foo
to look like this:
def foo(x, y):
print('X + Y:', x + y)
return x + y
How can I adapt args.func(args)
to handle this new foo
?
python argparse
I have the following CLI program which adds two numbers:
import argparse
def foo(args):
print('X + Y:', args.x + args.y)
return args.x + args.y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', type=int, default=1)
foo_parser.add_argument('-y', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(args)
Suppose now I want my users to also be able to import foo
and call it directly with arguments x
and y
. I.e. I want foo
to look like this:
def foo(x, y):
print('X + Y:', x + y)
return x + y
How can I adapt args.func(args)
to handle this new foo
?
python argparse
python argparse
edited Nov 5 at 4:46
asked Nov 5 at 4:13
Evidlo
484
484
One solution might involve something likeargs.func(*vars(args))
. I'm not sure how to removefunc
fromvars(args)
, though.
– Evidlo
Nov 5 at 4:22
def foo(x=0, y=0):
can be called a variety of ways.foo(1,2)
,foo(x=1, y=2)
,foo(**adict)
,foo(**vars(args))
.
– hpaulj
Nov 5 at 6:02
add a comment |
One solution might involve something likeargs.func(*vars(args))
. I'm not sure how to removefunc
fromvars(args)
, though.
– Evidlo
Nov 5 at 4:22
def foo(x=0, y=0):
can be called a variety of ways.foo(1,2)
,foo(x=1, y=2)
,foo(**adict)
,foo(**vars(args))
.
– hpaulj
Nov 5 at 6:02
One solution might involve something like
args.func(*vars(args))
. I'm not sure how to remove func
from vars(args)
, though.– Evidlo
Nov 5 at 4:22
One solution might involve something like
args.func(*vars(args))
. I'm not sure how to remove func
from vars(args)
, though.– Evidlo
Nov 5 at 4:22
def foo(x=0, y=0):
can be called a variety of ways. foo(1,2)
, foo(x=1, y=2)
, foo(**adict)
, foo(**vars(args))
.– hpaulj
Nov 5 at 6:02
def foo(x=0, y=0):
can be called a variety of ways. foo(1,2)
, foo(x=1, y=2)
, foo(**adict)
, foo(**vars(args))
.– hpaulj
Nov 5 at 6:02
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
The use of args.func(**vars(args))
is not a best fit for use-cases which require import as well as a CLI view
- When users import a function and call it, they expect a return value for further processing (nothing printed on a console. The caller can decide to print based on the result obtained)
- When they use a CLI, they expect to see an output printed on the console and a proper exit code (0 or 1 based on the return value)
The ideal way is to separate the parsing/CLI management/sum-function into separate functions and delegate processing once the parsing is complete (below is a sample example)
from __future__ import print_function # for python2
import argparse
def mysum(x, y=5):
return x+y
def delegator(input_args):
func_map = {
"mysum" : {
"func" : mysum,
"args": (input_args.get("x"),),
"kwargs" : {
"y" : input_args.get("y")
},
"result_renderer": print
}
}
func_data = func_map.get(input_args.get("action_to_perform"))
func = func_data.get("func")
args = func_data.get("args")
kwargs = func_data.get("kwargs")
renderer = func_data.get("result_renderer")
renderer(func(*args, **kwargs))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="action_to_perform")
foo_parser = subparsers.add_parser('mysum')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=3)
delegator(vars(parser.parse_args()))
Above example would also remove *args, **kwargs from your original function and lets the delegator send only what is needed by the function based on the command
You can extend it to support multiple commands
Hope this helps!
add a comment |
up vote
0
down vote
This is the cleanest way I've found so far:
import argparse
def foo(*, x, y, **kwargs):
print('X + Y:', x + y)
return x + y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(**vars(args))
Maybe someone else can find something better.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
The use of args.func(**vars(args))
is not a best fit for use-cases which require import as well as a CLI view
- When users import a function and call it, they expect a return value for further processing (nothing printed on a console. The caller can decide to print based on the result obtained)
- When they use a CLI, they expect to see an output printed on the console and a proper exit code (0 or 1 based on the return value)
The ideal way is to separate the parsing/CLI management/sum-function into separate functions and delegate processing once the parsing is complete (below is a sample example)
from __future__ import print_function # for python2
import argparse
def mysum(x, y=5):
return x+y
def delegator(input_args):
func_map = {
"mysum" : {
"func" : mysum,
"args": (input_args.get("x"),),
"kwargs" : {
"y" : input_args.get("y")
},
"result_renderer": print
}
}
func_data = func_map.get(input_args.get("action_to_perform"))
func = func_data.get("func")
args = func_data.get("args")
kwargs = func_data.get("kwargs")
renderer = func_data.get("result_renderer")
renderer(func(*args, **kwargs))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="action_to_perform")
foo_parser = subparsers.add_parser('mysum')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=3)
delegator(vars(parser.parse_args()))
Above example would also remove *args, **kwargs from your original function and lets the delegator send only what is needed by the function based on the command
You can extend it to support multiple commands
Hope this helps!
add a comment |
up vote
1
down vote
accepted
The use of args.func(**vars(args))
is not a best fit for use-cases which require import as well as a CLI view
- When users import a function and call it, they expect a return value for further processing (nothing printed on a console. The caller can decide to print based on the result obtained)
- When they use a CLI, they expect to see an output printed on the console and a proper exit code (0 or 1 based on the return value)
The ideal way is to separate the parsing/CLI management/sum-function into separate functions and delegate processing once the parsing is complete (below is a sample example)
from __future__ import print_function # for python2
import argparse
def mysum(x, y=5):
return x+y
def delegator(input_args):
func_map = {
"mysum" : {
"func" : mysum,
"args": (input_args.get("x"),),
"kwargs" : {
"y" : input_args.get("y")
},
"result_renderer": print
}
}
func_data = func_map.get(input_args.get("action_to_perform"))
func = func_data.get("func")
args = func_data.get("args")
kwargs = func_data.get("kwargs")
renderer = func_data.get("result_renderer")
renderer(func(*args, **kwargs))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="action_to_perform")
foo_parser = subparsers.add_parser('mysum')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=3)
delegator(vars(parser.parse_args()))
Above example would also remove *args, **kwargs from your original function and lets the delegator send only what is needed by the function based on the command
You can extend it to support multiple commands
Hope this helps!
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
The use of args.func(**vars(args))
is not a best fit for use-cases which require import as well as a CLI view
- When users import a function and call it, they expect a return value for further processing (nothing printed on a console. The caller can decide to print based on the result obtained)
- When they use a CLI, they expect to see an output printed on the console and a proper exit code (0 or 1 based on the return value)
The ideal way is to separate the parsing/CLI management/sum-function into separate functions and delegate processing once the parsing is complete (below is a sample example)
from __future__ import print_function # for python2
import argparse
def mysum(x, y=5):
return x+y
def delegator(input_args):
func_map = {
"mysum" : {
"func" : mysum,
"args": (input_args.get("x"),),
"kwargs" : {
"y" : input_args.get("y")
},
"result_renderer": print
}
}
func_data = func_map.get(input_args.get("action_to_perform"))
func = func_data.get("func")
args = func_data.get("args")
kwargs = func_data.get("kwargs")
renderer = func_data.get("result_renderer")
renderer(func(*args, **kwargs))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="action_to_perform")
foo_parser = subparsers.add_parser('mysum')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=3)
delegator(vars(parser.parse_args()))
Above example would also remove *args, **kwargs from your original function and lets the delegator send only what is needed by the function based on the command
You can extend it to support multiple commands
Hope this helps!
The use of args.func(**vars(args))
is not a best fit for use-cases which require import as well as a CLI view
- When users import a function and call it, they expect a return value for further processing (nothing printed on a console. The caller can decide to print based on the result obtained)
- When they use a CLI, they expect to see an output printed on the console and a proper exit code (0 or 1 based on the return value)
The ideal way is to separate the parsing/CLI management/sum-function into separate functions and delegate processing once the parsing is complete (below is a sample example)
from __future__ import print_function # for python2
import argparse
def mysum(x, y=5):
return x+y
def delegator(input_args):
func_map = {
"mysum" : {
"func" : mysum,
"args": (input_args.get("x"),),
"kwargs" : {
"y" : input_args.get("y")
},
"result_renderer": print
}
}
func_data = func_map.get(input_args.get("action_to_perform"))
func = func_data.get("func")
args = func_data.get("args")
kwargs = func_data.get("kwargs")
renderer = func_data.get("result_renderer")
renderer(func(*args, **kwargs))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="action_to_perform")
foo_parser = subparsers.add_parser('mysum')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=3)
delegator(vars(parser.parse_args()))
Above example would also remove *args, **kwargs from your original function and lets the delegator send only what is needed by the function based on the command
You can extend it to support multiple commands
Hope this helps!
answered Nov 8 at 14:40
pvpks
1066
1066
add a comment |
add a comment |
up vote
0
down vote
This is the cleanest way I've found so far:
import argparse
def foo(*, x, y, **kwargs):
print('X + Y:', x + y)
return x + y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(**vars(args))
Maybe someone else can find something better.
add a comment |
up vote
0
down vote
This is the cleanest way I've found so far:
import argparse
def foo(*, x, y, **kwargs):
print('X + Y:', x + y)
return x + y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(**vars(args))
Maybe someone else can find something better.
add a comment |
up vote
0
down vote
up vote
0
down vote
This is the cleanest way I've found so far:
import argparse
def foo(*, x, y, **kwargs):
print('X + Y:', x + y)
return x + y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(**vars(args))
Maybe someone else can find something better.
This is the cleanest way I've found so far:
import argparse
def foo(*, x, y, **kwargs):
print('X + Y:', x + y)
return x + y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(**vars(args))
Maybe someone else can find something better.
edited Nov 11 at 4:42
answered Nov 5 at 4:38
Evidlo
484
484
add a comment |
add a comment |
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%2f53148256%2fmake-functions-importable-when-using-argparse%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
One solution might involve something like
args.func(*vars(args))
. I'm not sure how to removefunc
fromvars(args)
, though.– Evidlo
Nov 5 at 4:22
def foo(x=0, y=0):
can be called a variety of ways.foo(1,2)
,foo(x=1, y=2)
,foo(**adict)
,foo(**vars(args))
.– hpaulj
Nov 5 at 6:02