[英]python unpacking arg list with *args and **kwargs along with other positional and keyword only params
我在名為 kwargs.py 的文件中定義了以下 function。 (將模塊更改為 unpacking.py 使 function 按預期工作)。 請參閱問題底部的圖像。
def tag(name, *content, cls=None, **attrs):
if cls is not None:
attrs['class'] = cls
if attrs:
attr_str = ''.join(' %s="%s"' % (key,val)
for key, val
in sorted(attrs.items()))
else:
attr_str = ''
if content:
return '\n'.join('<%s%s>%s</%s>' % (name,attr_str,c,name) for c in content)
else:
return '<%s%s />' % (name,attr_str)
執行此操作時
tag('div', 'testing', cls='test', **dict(id=33,alt='this is a test'))
我得到的結果是
'<div alt="this is a test" class="test" id="33">testing</div>'
但是當我執行這個
tag(**dict(name='div', content=('testing','and testing'), cls='test', id=33, alt='this is a test'))
我只得到
'<div alt="this is a test" class="test" id="33" />'
為什么要分配參數name
但未分配content
。 (即使元組沒有解包,我也希望至少元組本身被分配給 content[0])。
我在這里想念什么?
*content
不是論據。 你不能給它分配任何東西。
文檔確實沒有明確解釋。 它只是一個可以在 function 主體中使用的變量。 它的作用是“收集所有剩余的輸入參數”。
通常,這些可變參數 arguments 將在形式參數列表中排在最后,因為它們會收集傳遞給 function 的所有剩余輸入 arguments。
https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists
本 function
def func(*args, **kwargs):
print("args", args)
print("kwargs", kwargs)
func(args=[1, 2, 3])
將打印
args ()
kwargs {'args': [1, 2, 3]}
編輯:
你的例子是錯誤的。 您無法獲得不同的 output。
對於這個 function
def tag(name, *content, cls=None, **attrs):
if cls is not None:
attrs['class'] = cls
if attrs:
attr_str = ''.join(' %s="%s"' % (key, val)
for key, val
in sorted(attrs.items()))
else:
attr_str = ''
if content:
resp = '\n'.join('<%s%s>%s</%s>' % (name, attr_str, c, name) for c in content)
else:
resp = '<%s%s />' % (name, attr_str)
print("name", name)
print("*content", content)
print("cls", cls)
print("attrs", attrs)
print("attrs_str", attr_str)
print("resp", resp)
print('-'*10)
return resp
如果你運行這個
tag('div', 'testing', cls='test', **dict(id=33, alt='this is a test'))
tag(**dict(name='div', content=('testing','and testing'), cls='test', id=33, alt='this is a test'))
你得到
name div
*content ('testing',)
cls test
attrs {'id': 33, 'alt': 'this is a test', 'class': 'test'}
attrs_str alt="this is a test" class="test" id="33"
resp <div alt="this is a test" class="test" id="33">testing</div>
----------
name div
*content ()
cls test
attrs {'content': ('testing', 'and testing'), 'id': 33, 'alt': 'this is a test', 'class': 'test'}
attrs_str alt="this is a test" class="test" content="('testing', 'and testing')" id="33"
resp <div alt="this is a test" class="test" content="('testing', 'and testing')" id="33" />
----------
所以你不應該在第二種情況下得到'<div alt="this is a test" class="test" id="33" />'
。 對於完全相同的 function,我得到<div alt="this is a test" class="test" content="('testing', 'and testing')" id="33" />
。
編輯2:可能您的名稱空間已損壞,因為名稱**kwargs
經常以您在此處使用**attrs
的方式在其他地方使用,因此更改此模塊名稱/直接導入 function 應該可以解決您的問題。
首先讓我們確保我們使用相同的術語:
name, *content, cls=None, **attrs
),'div', 'testing', cls='test', **dict(id=33, alt='this is a test')
)。然后將 arguments 綁定到參數,因此可以在 function 主體中訪問它們。
首先讓我們看一下 function 簽名:
def tag(name, *content, cls=None, **attrs):
...
這個function定義了四個參數:
name
- 位置或關鍵字參數,content
- 一個可變參數參數,它捕獲任意數量的附加位置arguments,cls
- 具有默認值的僅限關鍵字的參數,attrs
- 一個關鍵字參數,它捕獲任意數量的附加關鍵字arguments。當您以下列方式調用此 function 時,會發生以下情況:
tag('div', 'testing', cls='test', **dict(id=33, alt='this is a test'))
'div'
綁定到name
,'testing'
被content
捕獲,產生一個 1 元組,'test'
綁定到cls
,id=33, alt='this is a test'
由attrs
捕獲。 現在關於*content
和**attrs
參數的特殊之處在於它們捕獲任意數量的多余 arguments 但它們不能直接綁定。 即你不能綁定content=(1, 2)
。 相反,如果你傳遞tag('foo', 1, 2)
這個綁定會自動發生。 因此,如果您通過以下方式調用 function:
tag(**dict(name='div', content=('testing', 'and testing'), cls='test', id=33, alt='this is a test'))
然后所有 arguments 都由關鍵字提供,因此除name
和cls
之外的所有內容都由attrs
捕獲。 這是因為*content
僅捕獲位置arguments。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.