簡體   English   中英

為什么可以將函數分配給type,const和default?

[英]Why can you assign functions to type, const and default?

我想了解為什么此代碼有效。 為什么要給typeconstdefault一個內置函數?

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中的一流對象,可以像其他任何對象一樣傳遞,因此沒有理由不能將它們用於constdefault


請注意,如果您確實提供了帶有'--sum'的參數,則args.accumulate將是該值:

>>> args = getParser().parse_args(["1", "--sum", "this one"])
('Integer:', '1')
>>> args.accumulate
'this one'

簡短答案:

argparse期望type是可調用的(對字符串的限制有限)。

argparse允許constdefault幾乎是任何東西。 除了將它們分配給屬性(或將它們傳遞給可調用的type )之外,它對它們沒有任何作用。

長答案:

在內部文檔中,對於class Action

  • 類型-可調用的類型,它接受單個字符串參數,並返回轉換后的值。 標准的Python類型str,int,float和complex是此類可調用對象的有用示例。 如果為None,則使用str。

  • 默認值-如果未指定該選項,則將產生的值。

  • const-如果指定了選項並且選項使用不帶值的操作,則將產生的值。

parse.add_argument創建一個Action ,使用action參數指定子類。 您可以交互地或通過以下方式查看此對象:

a = parser.add_argument(....)
print(repr(a))

typenargsdefault這樣的參數都存儲為該對象的屬性。

parse_args操作的某個深度parse_argsparser._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函數的工廠,該函數可以打開文件(即,獲取文件名並返回打開的文件)。

intfloat是內置的Python函數,它們接受字符串並返回值,或者在出現問題時引發錯誤。 這些指定用於轉換字符串的函數。 它們沒有直接指定字符串必須表示整數或浮點數。 用戶有時會錯誤地以相同方式使用boolean

_registries查找action參數。 所有默認操作類都有一個條目,因此我們使用諸如storestore_trueappend 但是我們也可以指定一個自定義的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=sumconst參數)。 但是--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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM