[英]Why can you assign functions to type, const and default?
I want to understand why this code works. 我想了解为什么此代码有效。 Why can you give
type
, const
and default
a built-in function? 为什么要给
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))
Output: 输出:
>>> Integer: 2
>>> Integer: 3
>>> Integer: 9
>>> Integer: 5
>>> ['2', '3', '9', '5']
>>> 9
I want to understand why it is working. 我想了解它为什么起作用。
Edit: 编辑:
You misunderstood me. 你误解我了。
For example "type" I would expect to see "type=int", because you want only to allow Integers. 例如,“ type”我希望看到“ type = int”,因为您只想允许Integers。 So you give "type" something.
所以你给“类型”一些东西。 But in my example "type" gives something to the "printList" functions, so that it can print it.
但是在我的示例中,“类型”为“ printList”函数提供了一些功能,以便可以打印它。 Or for example "default".
或例如“默认”。 I would expect to give some value, liken an int or str.
我希望给出一些值,例如int或str。 I give something to "default".
我给“默认”的东西。 But in my example I give the build-in function "max".
但是在我的示例中,我给内置函数“ max”。 Why does "max" get a list?
为什么“ max”获得列表? Why is that working?
为什么行得通? That is what I want to know.
这就是我想知道的。
parser.add_argument("--sum", dest="accumulate", const=sum, default=max, nargs="?")
is, assuming you don't supply an argument with '--sum'
, a little bit like: 是,假设你不提供与参数
'--sum'
,像一点点 :
args.accumulate = sum if '--sum' in arg_list else max
# ^ it also needs to be in the right place!
Per the docs for nargs='?'
根据
nargs='?'
: :
One argument will be consumed from the command line if possible, and produced as a single item.
如果可能,将从命令行使用一个参数,并将其作为单个项目产生。 If no command-line argument is present, the value from default will be produced.
如果不存在命令行参数,则将生成默认值。 Note that for optional arguments, there is an additional case - the option string is present but not followed by a command-line argument.
请注意,对于可选参数,还有另外一种情况-选项字符串存在,但后面没有命令行参数。 In this case the value from const will be produced.
在这种情况下,将产生const的值。
Functions are first-class objects in Python, and can be passed around like any other object, so there's no reason they can't be used for const
and default
. 函数是Python中的一流对象,可以像其他任何对象一样传递,因此没有理由不能将它们用于
const
和default
。
Note that if you actually did supply an argument with '--sum'
, args.accumulate
would be that value instead: 请注意,如果您确实提供了带有
'--sum'
的参数,则args.accumulate
将是该值:
>>> args = getParser().parse_args(["1", "--sum", "this one"])
('Integer:', '1')
>>> args.accumulate
'this one'
Short answer: 简短答案:
argparse
expects type
to be a callable (with limited provision for a string). argparse
期望type
是可调用的(对字符串的限制有限)。
argparse
allows const
and default
to be almost anything. argparse
允许const
和default
几乎是任何东西。 It doesn't do anything with them except assign them to an attribute (or pass them to your type
callable). 除了将它们分配给属性(或将它们传递给可调用的
type
)之外,它对它们没有任何作用。
Long answer: 长答案:
From the internal documentation, for class Action
: 在内部文档中,对于
class Action
:
type -- A callable that accepts a single string argument, and returns the converted value.
类型-可调用的类型,它接受单个字符串参数,并返回转换后的值。 The standard Python types str, int, float, and complex are useful examples of such callables.
标准的Python类型str,int,float和complex是此类可调用对象的有用示例。 If None, str is used.
如果为None,则使用str。
default -- The value to be produced if the option is not specified.
默认值-如果未指定该选项,则将产生的值。
const -- The value to be produced if the option is specified and the option uses an action that takes no values.
const-如果指定了选项并且选项使用不带值的操作,则将产生的值。
parse.add_argument
creates an Action
, using the action
parameter to specify the subclass. parse.add_argument
创建一个Action
,使用action
参数指定子类。 You can look at this object interactively or with: 您可以交互地或通过以下方式查看此对象:
a = parser.add_argument(....)
print(repr(a))
Parameters like type
, nargs
, default
are stored as attributes of this object. 像
type
, nargs
, default
这样的参数都存储为该对象的属性。
At some depth in the parse_args
action, parser._get_values()
ends up calling parser._get_value
on each string that is allocated to a particular action. 在
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)
This looks in a dictionary ( parser._registries
) to see if action.type
has been defined (as a string). 这将在字典(
parser._registries
)中action.type
是否已定义action.type
(作为字符串)。 If not, it assumes action.type
is itself a function. 如果不是,则假定
action.type
本身是一个函数。 The type
is used in the result = type_func(arg_string)
line. 该
type
用于result = type_func(arg_string)
行。
As a default None
is the only registered type
默认情况下,
None
是唯一注册的type
def identity(string):
return string
argparse.FileType
is a factory that creates a type
function, one that can open a file (ie take a file name and return an open file). argparse.FileType
是创建type
函数的工厂,该函数可以打开文件(即,获取文件名并返回打开的文件)。
int
, float
are builtin Python functions that take a string and return a value, or raise an error if there is a problem. int
, float
是内置的Python函数,它们接受字符串并返回值,或者在出现问题时引发错误。 These specify the function that is called to convert the string. 这些指定用于转换字符串的函数。 They do not, directly, specify that the string must represent an integer or float.
它们没有直接指定字符串必须表示整数或浮点数。 Users sometimes mistakenly use
boolean
in the same way. 用户有时会错误地以相同方式使用
boolean
。
The action
parameter is looked up in the _registries
. 在
_registries
查找action
参数。 All of the default action classes have an entry, hence we use values like store
, store_true
, and append
. 所有默认操作类都有一个条目,因此我们使用诸如
store
, store_true
和append
。 But we can also specify a custom Action class. 但是我们也可以指定一个自定义的Action类。
As for default
, early in the parse_args
stack, this line is executed for each action (defined argument): 对于
default
,在parse_args
堆栈的早期,对每个操作(定义的参数)执行以下行:
setattr(namespace, action.dest, action.default)
This makes not assumptions about the nature of action.default
. 这不对
action.default
的性质做任何假设。 It could be None
, a string, a number, a list, a function, or any Python object. 它可以是
None
,字符串,数字,列表,函数或任何Python对象。
Near the end of parse_args
, it may pass action.default
through the type
function. 在
parse_args
的结尾附近,它可能通过type
函数传递action.default
。 It does this only if default
is a string. 仅当
default
值为字符串时,它才执行此操作。
setattr(namespace, action.dest, self._get_value(action, action.default))
Look at your args
. 看看你的
args
。 It probably looks like: 它可能看起来像:
Namespace(integers=['2', '3', '9', '5'], accumulate=max)
Since you did not specify a --sum
option, the default value is placed in the namespace without change or checking. 由于未指定
--sum
选项,因此默认值无需更改或检查就放置在名称空间中。 If you had specified --sum
, but without an argument, then accumulate=sum
(the const
parameter) would be in the name space. 如果您指定了
--sum
,但没有参数,则名称空间中将为accumulate=sum
( const
参数)。 But --sum some_other_function
would have created accumulate="some_other_function"
. 但是
--sum some_other_function
应该会创建accumulate="some_other_function"
。
Your chosen type
function has the side effect of printing its input, but it returns the string unchanged, hence you see strings in the integers
list. 您选择的
type
函数具有打印其输入的副作用,但是它返回的字符串不变,因此您会在integers
列表中看到字符串。
When you execute 执行时
args.accumulate(args.integers)
It is the same as 与...相同
max(["2", "3", "9", "5"])
which returns "9"
- the string, not the number. 返回
"9"
-字符串,而不是数字。
sum(["2", "3", "9", "5"])
raise an error. 引发错误。 The misnamed
printList
only prints a string, not a list, and does not convert its values to integers. 命名错误的
printList
仅打印字符串,而不打印列表,并且不会将其值转换为整数。
Sorry to be long winded, but you did ask what is going on. 抱歉,请耐心等待,但您确实想知道这是怎么回事。 In short,
argparse
is written to give the user a lot of power, but it also tries to handle many common cases in a simple default manner. 简而言之,编写
argparse
可以为用户提供很多功能,但是它也尝试以一种简单的默认方式来处理许多常见情况。
Because functions are first-class objects in Python. 因为函数是Python中的一流对象。 They can be bound, accessed, and moved around just like any other type.
可以像其他任何类型一样绑定,访问和移动它们。
>>> foo = max
>>> foo(2, 3, 1)
3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.