如何使用 argparse 参数作为函数名
How to use argparse arguments as function names
我想实现 Argparse 介绍中的示例:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
但就我而言,我希望有更多可能的函数名称可供选择。
def a(): ...
def b(): ...
def c(): ...
parser.add_argument('-f', '--func',
choices=[a, b, c],
required=True,
help="""Choose one of the specified function to be run.""")
parser.func()
像这样使用它并没有按预期工作,我得到
$ python program.py -f=a
program.py: error: argument -f/--func: invalid choice: 'a' (choose from
<function a at 0x7fa15f32f5f0>,
<function b at 0x7fa15f32faa0>,
<function c at 0x7ff1967099b0>)
我知道我可以用基本的字符串参数和流控制来解决它,但如果我可以直接使用解析器参数作为函数名,它会更整洁,更容易维护。
您可以使用基本的字符串参数,并通过使用 dict
从名称中获取实际函数来尽量减少混乱。
我在Python 2.6.6,所以我不能使用argparse
,但是这段代码应该给你大概的思路:
#!/usr/bin/env python
def a(): return 'function a'
def b(): return 'function b'
def c(): return 'function c'
func_list = [a, b, c]
func_names = [f.func_name for f in func_list]
funcs_dict = dict(zip(func_names, func_list))
f = funcs_dict['b']
print f()
输出
function b
因此您可以将 func_names
传递给 argparse
并使用 funcs_dict
.
紧凑地检索所需的函数
在较新的 Python 版本中,您应该使用 f.__name__
而不是 f.func_name
。 (这也适用于 Python 2.6,但我在写这个答案时不熟悉较新的语法)。
您需要确保您的 choice
是字符串(用户不能在命令行输入 Python 函数对象)。您可以使用字典将这些字符串解析为函数。例如:
# Example functions:
def a(i):
return i + 1
def b(i):
return i + 2
def c(i):
return i + 3
# a dictionary mapping strings of function names to function objects:
funcs = {'a': a, 'b': b, 'c': c}
# Add the -f/--func argument: valid choices are function _names_
parser.add_argument('-f', '--func', dest='func',
choices=['a', 'b', 'c'],
required=True,
help="""Choose one of the specified function to be run.""")
args = parser.parse_args()
# Resolve the chosen function object using its name:
chosen_func = funcs[args.func]
我的分析,可能有误,但这是我的理解。
ArgParse 允许您通过强制转换机制从命令行参数创建不仅仅是简单的对象。
如果您传递字符串“5”并指定您正在等待一个整数,这会让您得到数字 5。
实际上您正试图从字符串 'a' 中获取一个函数。没有铸造方法可以做到这一点。这是我解决您问题的建议:
import argparse
def foo():
print("called foo")
def bar():
print("called bar")
functions = [foo, bar] #list your functions here
functions = { function.__name__ : function for function in functions}
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--func',
choices=list(functions.keys()),
required=True,
help="""Choose one of the specified function to be run.""")
args = parser.parse_args()
functions[args.func]()
你现在只需在开始时将你的函数注册到列表函数中,并在最后一行之后调用它们,这要归功于从函数列表构建并自动替换的函数索引
我想实现 Argparse 介绍中的示例:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
但就我而言,我希望有更多可能的函数名称可供选择。
def a(): ...
def b(): ...
def c(): ...
parser.add_argument('-f', '--func',
choices=[a, b, c],
required=True,
help="""Choose one of the specified function to be run.""")
parser.func()
像这样使用它并没有按预期工作,我得到
$ python program.py -f=a
program.py: error: argument -f/--func: invalid choice: 'a' (choose from
<function a at 0x7fa15f32f5f0>,
<function b at 0x7fa15f32faa0>,
<function c at 0x7ff1967099b0>)
我知道我可以用基本的字符串参数和流控制来解决它,但如果我可以直接使用解析器参数作为函数名,它会更整洁,更容易维护。
您可以使用基本的字符串参数,并通过使用 dict
从名称中获取实际函数来尽量减少混乱。
我在Python 2.6.6,所以我不能使用argparse
,但是这段代码应该给你大概的思路:
#!/usr/bin/env python
def a(): return 'function a'
def b(): return 'function b'
def c(): return 'function c'
func_list = [a, b, c]
func_names = [f.func_name for f in func_list]
funcs_dict = dict(zip(func_names, func_list))
f = funcs_dict['b']
print f()
输出
function b
因此您可以将 func_names
传递给 argparse
并使用 funcs_dict
.
在较新的 Python 版本中,您应该使用 f.__name__
而不是 f.func_name
。 (这也适用于 Python 2.6,但我在写这个答案时不熟悉较新的语法)。
您需要确保您的 choice
是字符串(用户不能在命令行输入 Python 函数对象)。您可以使用字典将这些字符串解析为函数。例如:
# Example functions:
def a(i):
return i + 1
def b(i):
return i + 2
def c(i):
return i + 3
# a dictionary mapping strings of function names to function objects:
funcs = {'a': a, 'b': b, 'c': c}
# Add the -f/--func argument: valid choices are function _names_
parser.add_argument('-f', '--func', dest='func',
choices=['a', 'b', 'c'],
required=True,
help="""Choose one of the specified function to be run.""")
args = parser.parse_args()
# Resolve the chosen function object using its name:
chosen_func = funcs[args.func]
我的分析,可能有误,但这是我的理解。
ArgParse 允许您通过强制转换机制从命令行参数创建不仅仅是简单的对象。 如果您传递字符串“5”并指定您正在等待一个整数,这会让您得到数字 5。
实际上您正试图从字符串 'a' 中获取一个函数。没有铸造方法可以做到这一点。这是我解决您问题的建议:
import argparse
def foo():
print("called foo")
def bar():
print("called bar")
functions = [foo, bar] #list your functions here
functions = { function.__name__ : function for function in functions}
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--func',
choices=list(functions.keys()),
required=True,
help="""Choose one of the specified function to be run.""")
args = parser.parse_args()
functions[args.func]()
你现在只需在开始时将你的函数注册到列表函数中,并在最后一行之后调用它们,这要归功于从函数列表构建并自动替换的函数索引