【Python】**kwargs和takes 1 positional argument but 2 were given


Python的函數定義中可以在參數里添加**kwargs——簡單來說目的是允許添加不定參數名稱的參數,並作為字典傳遞參數。但前提是——你必須提供參數名

例如下述情況:

1 class C():
2     def __init__(self, **kwargs):
3         print(kwargs)

 

有如下輸入:

In [48]: c = C()
{}

In [49]: c = C(a = 1)
{'a': 1}

 

這一切都符合常理。但是當我使用一個字典傳遞的時候:

In [50]: c = C({'a': 1})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-50-2be6d5be2a84> in <module>()
----> 1 c = C({'a': 1})

 

我一開始以為是__init__太嬌氣了,換成一般辦法:

1 In [51]: class C():
2     ...:     def f(self, **kwargs):
3     ...:         print(kwargs)
4     ...:

 

In [52]: c = C()

In [53]: c.f({'a': 1})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-53-5daee03baab1> in <module>()
----> 1 c.f({'a': 1})

TypeError: f() takes 1 positional argument but 2 were given

 

包括定義在__main__下的函數也是如此:

In [54]: def f1(**kwargs):
    ...:     print(kwargs)
    ...:

In [56]: f1({'a': 1})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-56-8652a6e75162> in <module>()
----> 1 f1({'a': 1})

TypeError: f1() takes 0 positional arguments but 1 was given

 

但是當我在f1參數前加一個參數名

1 In [57]: f1(b = {'a': 1})
2 {'b': {'a': 1}}

 

問題立刻解決。

 


 

思考:

我們在先前的錯誤嘗試中,一直傳入的是個單純的字典。雖然**kwargs提供將參數轉成字典的功能,但是直接傳入字典並不會使其理解成參數。實質上Python解釋器認為我們輸入的是作為參數值的字典,而並未攜帶參數名稱,而Python函數機制中“固定名稱”的參數應寫在**kwargs的前面,因此誤以為我們傳入了一個“固定名稱”參數,事實上我們先前的定義中並未加入“固定名稱”參數,所以報錯takes 1 positional arguments but 2 was given

如果真的要傳入字典怎么辦呢?這就簡單了,直接把**kwargs改成kwargs即可:

1 In [58]: class C():
2     ...:     def __init__(self, kwargs):
3     ...:         print(kwargs)
4     ...:
5 
6 In [59]: c = C({'a': 1})
7 {'a': 1}

 

這次經歷使我加深了對**kwargs特殊參數的理解。以后的學習更要注意細節!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM