[英]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.