[英]Why can you assign functions to type, const and default?
我想了解为什么此代码有效。 为什么要给type
, const
和default
一个内置函数?
def printList(i):
print("Integer:", i)
return(i)
def getParser():
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("integers", type=printList, nargs="+")
parser.add_argument("--sum", dest="accumulate", const=sum, default=max, nargs="?")
return(parser)
args = getParser().parse_args(["2", "3", "9", "5"])
print(args.integers)
print(args.accumulate(args.integers))
输出:
>>> Integer: 2
>>> Integer: 3
>>> Integer: 9
>>> Integer: 5
>>> ['2', '3', '9', '5']
>>> 9
我想了解它为什么起作用。
编辑:
你误解我了。
例如,“ type”我希望看到“ type = int”,因为您只想允许Integers。 所以你给“类型”一些东西。 但是在我的示例中,“类型”为“ printList”函数提供了一些功能,以便可以打印它。 或例如“默认”。 我希望给出一些值,例如int或str。 我给“默认”的东西。 但是在我的示例中,我给内置函数“ max”。 为什么“ max”获得列表? 为什么行得通? 这就是我想知道的。
parser.add_argument("--sum", dest="accumulate", const=sum, default=max, nargs="?")
是,假设你不提供与参数'--sum'
,像一点点 :
args.accumulate = sum if '--sum' in arg_list else max
# ^ it also needs to be in the right place!
根据nargs='?'
:
如果可能,将从命令行使用一个参数,并将其作为单个项目产生。 如果不存在命令行参数,则将生成默认值。 请注意,对于可选参数,还有另外一种情况-选项字符串存在,但后面没有命令行参数。 在这种情况下,将产生const的值。
函数是Python中的一流对象,可以像其他任何对象一样传递,因此没有理由不能将它们用于const
和default
。
请注意,如果您确实提供了带有'--sum'
的参数,则args.accumulate
将是该值:
>>> args = getParser().parse_args(["1", "--sum", "this one"])
('Integer:', '1')
>>> args.accumulate
'this one'
简短答案:
argparse
期望type
是可调用的(对字符串的限制有限)。
argparse
允许const
和default
几乎是任何东西。 除了将它们分配给属性(或将它们传递给可调用的type
)之外,它对它们没有任何作用。
长答案:
在内部文档中,对于class Action
:
类型-可调用的类型,它接受单个字符串参数,并返回转换后的值。 标准的Python类型str,int,float和complex是此类可调用对象的有用示例。 如果为None,则使用str。
默认值-如果未指定该选项,则将产生的值。
const-如果指定了选项并且选项使用不带值的操作,则将产生的值。
parse.add_argument
创建一个Action
,使用action
参数指定子类。 您可以交互地或通过以下方式查看此对象:
a = parser.add_argument(....)
print(repr(a))
像type
, nargs
, default
这样的参数都存储为该对象的属性。
在parse_args
操作的某个深度parse_args
, parser._get_values()
最终在分配给特定操作的每个字符串上调用parser._get_value
。
def _get_value(self, action, arg_string):
type_func = self._registry_get('type', action.type, action.type)
if not callable(type_func):
msg = _('%r is not callable')
raise ArgumentError(action, msg % type_func)
# convert the value to the appropriate type
try:
result = type_func(arg_string)
这将在字典( parser._registries
)中action.type
是否已定义action.type
(作为字符串)。 如果不是,则假定action.type
本身是一个函数。 该type
用于result = type_func(arg_string)
行。
默认情况下, None
是唯一注册的type
def identity(string):
return string
argparse.FileType
是创建type
函数的工厂,该函数可以打开文件(即,获取文件名并返回打开的文件)。
int
, float
是内置的Python函数,它们接受字符串并返回值,或者在出现问题时引发错误。 这些指定用于转换字符串的函数。 它们没有直接指定字符串必须表示整数或浮点数。 用户有时会错误地以相同方式使用boolean
。
在_registries
查找action
参数。 所有默认操作类都有一个条目,因此我们使用诸如store
, store_true
和append
。 但是我们也可以指定一个自定义的Action类。
对于default
,在parse_args
堆栈的早期,对每个操作(定义的参数)执行以下行:
setattr(namespace, action.dest, action.default)
这不对action.default
的性质做任何假设。 它可以是None
,字符串,数字,列表,函数或任何Python对象。
在parse_args
的结尾附近,它可能通过type
函数传递action.default
。 仅当default
值为字符串时,它才执行此操作。
setattr(namespace, action.dest, self._get_value(action, action.default))
看看你的args
。 它可能看起来像:
Namespace(integers=['2', '3', '9', '5'], accumulate=max)
由于未指定--sum
选项,因此默认值无需更改或检查就放置在名称空间中。 如果您指定了--sum
,但没有参数,则名称空间中将为accumulate=sum
( const
参数)。 但是--sum some_other_function
应该会创建accumulate="some_other_function"
。
您选择的type
函数具有打印其输入的副作用,但是它返回的字符串不变,因此您会在integers
列表中看到字符串。
执行时
args.accumulate(args.integers)
与...相同
max(["2", "3", "9", "5"])
返回"9"
-字符串,而不是数字。
sum(["2", "3", "9", "5"])
引发错误。 命名错误的printList
仅打印字符串,而不打印列表,并且不会将其值转换为整数。
抱歉,请耐心等待,但您确实想知道这是怎么回事。 简而言之,编写argparse
可以为用户提供很多功能,但是它也尝试以一种简单的默认方式来处理许多常见情况。
因为函数是Python中的一流对象。 可以像其他任何类型一样绑定,访问和移动它们。
>>> foo = max
>>> foo(2, 3, 1)
3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.