python參數傳遞*args和**kwargs

python參數傳遞*args和**kwargs

*

實際上真正的Python參數傳遞語法是 ****args**kwargs 只是一種約定俗成的編程實踐。我們也可以寫成 *vars**kvars 。就如同其他常規變量的命名一樣, argskwargs 只是一種習慣的名稱。

*args**kwargs 一般是用在函數定義的時候。二者的意義是允許定義的函數接受任意數量的參數。也就是說我們在函數被調用前并不知道也不限制將來函數可以接收的參數數量。在這種情況下我們可以使用 *args**kwargs

接下來我們分別分析 *args**kwargs 在函數定義時(即在形參列表中)和在函數調用時的用法。

在函數定義時的*和**(即函數形參列表中的*和**)

在函數定義時的*args

*args 用來表示函數接收可變長度的非關鍵字參數列表作為函數的輸入。我們通過一個例子來體會參數列表中的 *args 的用法:

def test_args(normal_arg, *args):print("normal arg:" + normal_arg)print(type(args))for arg in args:print("another arg through *args :" + arg)test_args("normal", "Python", "C", "C++")

輸出:

normal arg:normal
<class 'tuple'>
another arg through *args :Python
another arg through *args :C
another arg through *args :C++

在函數定義時的**kwargs

**kwargs 表示函數接收可變長度的關鍵字參數字典作為函數的輸入。當我們需要函數接收帶關鍵字的參數作為輸入的時候,應當使用 **kwargs。我們可以通過以下這個例子來進一步理解 **kwargs

def test_kwargs(**kwargs):if kwargs is not None:print(type(kwargs))for key, value in kwargs.items():print("{} = {}".format(key,value))test_kwargs(name="python", value="5")

輸出:

<class 'dict'>
name = python
value = 5

如何處理關鍵字參數中的未知性

雖說參數列表中的 *和**使得我們可以接收任意多個參數變量,但是我們在設計函數時肯定也不是隨便什么參數都去處理的,函數的調用者應該明白在 *args**kwargs 中需要傳遞什么參數,可以傳遞什么參數(比如深度學習模型中的模型結構的設置,如模型深度,dropout概率等)。并且我們在函數體中來處理這些參數。

然而,我們并不知道調用者在調用時會傳什么,哪些又應該在調用時使用默認值。這里筆者參考了 timm 視覺庫對 ViT 的實現。

在_create_vision_trainsformer 函數中,我們只要處理和我們相關的傳入參數:

def _create_vision_transformer(variant, pretrained=False, default_cfg=None, **kwargs):default_cfg = default_cfg or default_cfgs[variant]if kwargs.get('features_only', None):raise RuntimeError('features_only not implemented for Vision Transformer models.')# NOTE this extra code to support handling of repr size for in21k pretrained modelsdefault_num_classes = default_cfg['num_classes']num_classes = kwargs.get('num_classes', default_num_classes)repr_size = kwargs.pop('representation_size', None)if repr_size is not None and num_classes != default_num_classes:# Remove representation layer if fine-tuning. This may not always be the desired action,# but I feel better than doing nothing by default for fine-tuning. Perhaps a better interface?_logger.warning("Removing representation layer for fine-tuning.")repr_size = Nonemodel = build_model_with_cfg(VisionTransformer, variant, pretrained,default_cfg=default_cfg,representation_size=repr_size,pretrained_filter_fn=checkpoint_filter_fn,pretrained_custom_load='npz' in default_cfg['url'],**kwargs)return model

可以看到,我們傳入的 kwargs 是一個字典,這里使用了字典的 getpop 兩種方法來處理。

python字典的get和pop方法

pop

dict.pop(key[,default])

刪除字典給定鍵 key 及對應的值,返回值為被刪除的值,若 key 不存在,則返回 default 參數所指定的默認值。

get

dict.get(key, default=None)

函數返回指定鍵的值,若 key 不存在,則返回 default 參數所指定的默認值。

通過這兩種方法,我們就能夠實現在 kwargs 中沒有傳入參數時使用默認值,而在有指定參數時,使用傳入值。

在函數調用時的*和**

  • 列表前面加星號作用是將列表解開成兩個獨立的參數,傳入函數,

  • 字典前面加兩個星號,是將字典解開成獨立的元素作為形參。

如果我們有一個加法函數 add()

def add(a, b):return a + b

函數調用時的*

我們可以這樣調用它:先構造一個列表,在用 * 將列表解開,將其中的值作為參數逐個傳入函數的參數列表:

data_list = [1, 2]
print(add(*data_list))
# 輸出:3

就相當于

print(add(1, 2))

我們甚至可以直接打印出 * 解開列表之后的參數序列:

print(*data_list)
# 輸出:1 2

函數調用時的**

我們還可用字典的形式來調用它:構造一個字典,鍵名為要調用函數的形參名稱,值為我們要傳遞的參數:

data_dict = {'a': 1, 'b': 2}
print(add(**data_dict))
# 輸出:3

相當于:

print(add(a=1, b=2))

注意這里我們構造的字典的鍵名必須對應函數形參列表中的形參名稱,否則匯報錯,比如

data_dict = {'a': 1, 'c': 2}
print(add(**data_dict))

相當于:

print(data(a=1, c=2))

將會報錯:

TypeError: add() got an unexpected keyword argument 'c'

兩種使用方式的統一理解

以關鍵字參數 **kwargs 為例,我們這樣考慮:

我們提到過,對于一個字典 dict={'a': 1, 'b': 2} ,給它加上 ** 號 ,相當于是將其中的元素解開單拎出來,即 **dict 相當于 a=1, b=2,這正好符合我們調用函數傳遞參數時的寫法。

而當 **kwargs 在中形參列表中時,我們傳入 a=1, b=2,看一下,正好對應我們上面的 **dict (只是名字不一樣,開始提到過,這無妨),那也把 ** 號去掉后,kwargs 就相當于我們上面的 dict ,是一個字典:{'a': 1, 'b': 2} ,這就說明了為什么我們上面介紹函數定義時的 **kwargs 的例子中,type(kwargs)dict,并且在函數體中我們也是通過調用字典類的方法(如 itemspopget)來處理它。

Ref:

https://www.jianshu.com/p/be92113116c8

https://github.com/rwightman/pytorch-image-models

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532648.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532648.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532648.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

聽GPT 講Rust源代碼--src/tools(25)

File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs 在Rust源代碼中&#xff0c;suspicious_command_arg_space.rs文件位于clippy_lints工具包的methods目錄下&#xff0c;用于實現Clippy lint SUSPICIOUS_COMMAND_ARG_SPACE。 Clippy是Ru…

Java一次編譯,到處運行是如何實現的

Java一次編譯&#xff0c;到處運行是如何實現的 轉自&#xff1a;https://cloud.tencent.com/developer/article/1415194 &#xff08;排版微調&#xff09; JAVA編譯運行總覽 Java是一種高級語言&#xff0c;要讓計算機執行你撰寫的Java程序&#xff0c;也得通過編譯程序的…

JIT(動態編譯)和AOT(靜態編譯)編譯技術比較

JIT&#xff08;動態編譯&#xff09;和AOT&#xff08;靜態編譯&#xff09;編譯技術比較 轉自&#xff1a;https://www.cnblogs.com/tinytiny/p/3200448.html Java 應用程序的性能經常成為開發社區中的討論熱點。因為該語言的設計初衷是使用解釋的方式支持應用程序的可移植…

python解釋器

python解釋器 計算機編程語言 本部分參考自&#xff1a;https://zhuanlan.zhihu.com/p/141212114 從計算機編程語言說起&#xff0c;它主要分為三類&#xff1a;機器語言、匯編語言、高級語言。 機器語言是一種計算機可以直接識別并執行的二進制指令集。由于其可以直接交給…

編譯型語言與解釋型語言

編譯型語言與解釋型語言 首先要說明&#xff0c;編譯型語言與解釋型語言這種分類方法是不科學的&#xff0c;或者說已經過時了&#xff0c;但是這種稱呼大抵還是能夠讓人明白我們將要討論的是什么東西。 文中所列參考是筆者認為比較有幫助的一些擴展閱讀內容。 首先貼一個很形…

常見的各種shell及其區別

常見的各種shell及其區別 引子 for((i1;i<10;i)); do echo $(expr $i \* 3 1); done 網上搜到的 shell for循環腳本&#xff0c;別人都能正常運行&#xff0c;我卻報錯&#xff1a; Syntax error: Bad for loop variable究竟是怎么回事呢&#xff1f; shell簡介…

shell腳本 變量

shell腳本 變量類型 什么是Shell變量 用一個固定的字符串去表示不固定的內容。 Shell變量的類型 shell腳本中自定義變量的類型&#xff0c;我們這里分為&#xff1a; 自定義變量環境變量位置變量與定義變量 這四類&#xff0c;它們有一些相同點&#xff0c;但又有些不同點…

攻防世界web新手區解題 /cookie / disabled_button / weak_auth

cookie 題目描述&#xff1a;X老師告訴小寧他在cookie里放了些東西&#xff0c;小寧疑惑地想&#xff1a;‘這是夾心餅干的意思嗎&#xff1f;’ 使用burp suite抓包查看 發現提示&#xff1a; look-herecookie.php 于是在url后加上 cookie.php 得到提示查看返回 就得到了f…

Python 函數式編程

Python 函數式編程 轉自&#xff1a;https://www.liaoxuefeng.com/wiki/1016959663602400/1017328525009056&#xff0c;推薦去該鏈接讀原文&#xff0c;有習題和熱烈的評論區交流。 函數式編程 函數是Python內建支持的一種封裝&#xff0c;我們通過把大段代碼拆成函數&…

Python中的生成器與迭代器

Python中的生成器與迭代器 轉自&#xff1a;https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640&#xff0c;推薦去該鏈接讀原文&#xff0c;有習題和熱烈的評論區交流。 生成器 通過列表生成式&#xff0c;我們可以直接創建一個列表。但是&#xff0c;受…

基于GET報錯的sql注入,sqli-lab 1~4

根據注入類型可將sql注入分為兩類&#xff1a;數字型和字符型 例如&#xff1a; 數字型&#xff1a; sleect * from table where if 用戶輸入id 字符型&#xff1a;select * from table where id 用戶輸入id &#xff08;有引號) 通過URL中修改對應的D值&#xff0c;為正常數字…

Python 裝飾器詳解(上)

Python 裝飾器詳解&#xff08;上&#xff09; 轉自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84396970&#xff0c;博主僅對其中 demo 實現中不適合python3 版本的語法進行修改&#xff0c;并微調了排版&#xff0c;本轉載博客全部例程博主均已親測可行…

xss原理和注入類型

XSS漏洞原理 : XSS又叫CSS(cross Site Script), 跨站腳本攻擊,指的是惡意攻擊者往Web頁面里插入惡意JS代碼,當用戶瀏覽該頁時,嵌入其中的Web里的JS代碼就會被執行,從而達到惡意的特殊目的. 比如:拿到cooike XSS漏洞分類: 反射性(非存儲型) payload沒有經過存儲,后端接收后,直接…

Python 裝飾器詳解(中)

Python 裝飾器詳解&#xff08;中&#xff09; 轉自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84581272&#xff0c;博主僅對其中 demo 實現中不適合python3 版本的語法進行修改&#xff0c;并微調了排版&#xff0c;本轉載博客全部例程博主均已親測可行…

存儲型xss案例

存儲型xss原理: 攻擊者在頁面插入xss代碼,服務端將數據存入數據庫,當用戶訪問存在xss漏洞的頁面時,服務端從數據庫取出數據展示到頁面上,導致xss代碼執行,達到攻擊效果 案例: 在一個搭建的論壇網站中, 根據存儲型xss注入的條件,要找到可以存儲到數據庫的輸入位置,并且這個位置…

反射型XSS案例

**原理:**攻擊者將url中插入xss代碼,服務端將url中的xss代碼輸出到頁面上,攻擊者將帶有xss代碼的url發送給用戶,用戶打開后受到xss攻擊 需要url中有可以修改的參數 案例: 可能存在反射型xss的功能(點) : 搜索框等&#xff08;所有url會出現參數的地方都可以嘗試&#xff09;……

Python 裝飾器詳解(下)

Python 裝飾器詳解&#xff08;下&#xff09; 轉自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84627016&#xff0c;博主僅對其中 demo 實現中不適合python3 版本的語法進行修改&#xff0c;并微調了排版&#xff0c;本轉載博客全部例程博主均已親測可行…

xss-lab靶場通關writeup(1~6.......在更新)

level 2 : 標簽被編碼&#xff0c;利用屬性完成彈窗 輸入 發現沒有彈窗 查看源代碼&#xff1a; 發現&#xff1a; <>符號被編碼 說明keybord參數進行了處理&#xff0c;那么只能從屬性上進行惡意編碼&#xff1a;先將屬性的引號和標簽閉合&#xff0c;用 // 將后面的…

PyTorch 分布式訓練DDP 單機多卡快速上手

PyTorch 分布式訓練DDP 單機多卡快速上手 本文旨在幫助新人快速上手最有效的 PyTorch 單機多卡訓練&#xff0c;對于 PyTorch 分布式訓練的理論介紹、多方案對比&#xff0c;本文不做詳細介紹&#xff0c;有興趣的讀者可參考&#xff1a; [分布式訓練] 單機多卡的正確打開方式…

Linux free 命令詳解

Linux free 命令詳解 free 命令用來查看系統中已用的和可用的內存。 命令選項及輸出簡介 關于各種命令的功能和命令選項&#xff0c;還是推薦英語比較好的同學直接看手冊 RTFM&#xff1a;man free。這里簡單總結一下一些重點&#xff1a; 功能及輸出簡介 free 命令顯示系…