使用 argparse 处理 if-else 的最佳方法?
Best way to handle if-else with argparse?
假设我们有很多参数解析选项
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Download files from Canvas.')
parser.add_argument(
'-user_id',
type=str,
default="",
)
parser.add_argument(
'-course_id',
type=str,
default="",
)
parser.add_argument(
'-student_id',
type=str,
default="",
)
# ...
parser.add_argument(
'-book_id',
type=str,
default="",
)
我想运行函数由输入
决定
if user_id != "" and course_id == "" and student_id != "" and book_id == "":
f()
elif user_id != "" and course_id == "" and student_id != "" and book_id != "":
g()
# ...
elif user_id == "" and course_id == "" and student_id == "" and book_id == "":
h()
等等。嗯,这些是很多 if-else 语句。我想消除必须做所有这些。有没有人有足够的方法来减少函数 运行 之前变量之间的比较量?还是取决于上下文?谢谢!!
构建一个将选项组合映射到处理程序函数的字典。
当你这样写的时候:
if user_id != "" and course_id == "" and student_id != "" and book_id == "":
您实际上是将这四个选项视为布尔元组
值。你在问,“参数是否等于(假,真,
假,真)?”
我们可以利用这一点。首先,我们需要代码来翻译
选项到一个实际的元组中。类似于:
args = parser.parse_args()
sig = tuple(getattr(args, x) == '' for x in ('user_id', 'course_id', 'student_id', 'book_id'))
如果您的程序没有接收到命令行参数,这会设置 sig
等于 (True, True, True, True)
。如果你通过了--student-id 1
,
这变成 (True, True, False, True)
.
我们可以创建一个将这些模式映射到处理程序的字典
功能:
argmap = {
(False, True, False, True): f,
(False, True, False, False): g,
(True, True, True, True): h,
}
有了这两种机制,我们就可以查找处理程序
给定一组这样的参数:
handler = argmap.get(sig)
if handler is None:
print('no handler for', args)
else:
handler()
将它们放在一起,我们得到:
import argparse
def f():
print('this is function f')
def g():
print('this is function g')
def h():
print('this is function h')
argmap = {
(False, True, False, True): f,
(False, True, False, False): g,
(True, True, True, True): h,
}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Download files from Canvas.')
parser.add_argument(
'--user-id',
default='',
)
parser.add_argument(
'--course-id',
default='',
)
parser.add_argument(
'--student-id',
default='',
)
parser.add_argument(
'--book-id',
default='',
)
args = parser.parse_args()
sig = tuple(getattr(args, x) == '' for x in ('user_id', 'course_id', 'student_id', 'book_id'))
handler = argmap.get(sig)
if handler is None:
print('no handler for', args)
else:
handler()
这产生了输出:
$ python argtest.py
this is function h
$ python argtest.py --user-id 1 --student-id 1
this is function f
$ python argtest.py --user-id 1 --student-id 1 --book-id 1
this is function g
$ python argtest.py --user-id 1
no handler for Namespace(user_id='1', course_id='', student_id='', book_id='')
假设我们有很多参数解析选项
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Download files from Canvas.')
parser.add_argument(
'-user_id',
type=str,
default="",
)
parser.add_argument(
'-course_id',
type=str,
default="",
)
parser.add_argument(
'-student_id',
type=str,
default="",
)
# ...
parser.add_argument(
'-book_id',
type=str,
default="",
)
我想运行函数由输入
决定if user_id != "" and course_id == "" and student_id != "" and book_id == "":
f()
elif user_id != "" and course_id == "" and student_id != "" and book_id != "":
g()
# ...
elif user_id == "" and course_id == "" and student_id == "" and book_id == "":
h()
等等。嗯,这些是很多 if-else 语句。我想消除必须做所有这些。有没有人有足够的方法来减少函数 运行 之前变量之间的比较量?还是取决于上下文?谢谢!!
构建一个将选项组合映射到处理程序函数的字典。
当你这样写的时候:
if user_id != "" and course_id == "" and student_id != "" and book_id == "":
您实际上是将这四个选项视为布尔元组 值。你在问,“参数是否等于(假,真, 假,真)?”
我们可以利用这一点。首先,我们需要代码来翻译 选项到一个实际的元组中。类似于:
args = parser.parse_args()
sig = tuple(getattr(args, x) == '' for x in ('user_id', 'course_id', 'student_id', 'book_id'))
如果您的程序没有接收到命令行参数,这会设置 sig
等于 (True, True, True, True)
。如果你通过了--student-id 1
,
这变成 (True, True, False, True)
.
我们可以创建一个将这些模式映射到处理程序的字典 功能:
argmap = {
(False, True, False, True): f,
(False, True, False, False): g,
(True, True, True, True): h,
}
有了这两种机制,我们就可以查找处理程序 给定一组这样的参数:
handler = argmap.get(sig)
if handler is None:
print('no handler for', args)
else:
handler()
将它们放在一起,我们得到:
import argparse
def f():
print('this is function f')
def g():
print('this is function g')
def h():
print('this is function h')
argmap = {
(False, True, False, True): f,
(False, True, False, False): g,
(True, True, True, True): h,
}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Download files from Canvas.')
parser.add_argument(
'--user-id',
default='',
)
parser.add_argument(
'--course-id',
default='',
)
parser.add_argument(
'--student-id',
default='',
)
parser.add_argument(
'--book-id',
default='',
)
args = parser.parse_args()
sig = tuple(getattr(args, x) == '' for x in ('user_id', 'course_id', 'student_id', 'book_id'))
handler = argmap.get(sig)
if handler is None:
print('no handler for', args)
else:
handler()
这产生了输出:
$ python argtest.py
this is function h
$ python argtest.py --user-id 1 --student-id 1
this is function f
$ python argtest.py --user-id 1 --student-id 1 --book-id 1
this is function g
$ python argtest.py --user-id 1
no handler for Namespace(user_id='1', course_id='', student_id='', book_id='')