《流畅的Python》p254
简单讲,如果在函数形参列表定义了一个变量名前带 ** 的变量,并且在调用函数传参的时候把一个字典类型变量前面也加上 ** 并传给参数,那么传入的这个字典类型里但凡有键名和被调函数形参列表同名的键值对,这些键值对的值都会被赋给形参列表中对应的同名参数(形参列表里 前头带一个星星 * 的变量除外,原因还不懂)。其余的键值对,会被形参列表里带 ** 的参数捕获,并创建成一个字典。
"""
关于 ** 的笔记
"""
# note:
# 第一个参数后面的任意个参数会被 *content 捕获,存入一个元组。
def tag(name, *content, cls=None, **attrs):
"""生成一个或多个HTML标签"""
if cls is not None: # 如果 cls 参数不空的话,在字典 attrs 中创建键值对 'class':cls
attrs['class'] = cls
if attrs: # 如果 attrs 参数不空的话,把 attrs 中所有的键值对都连接成字符串,赋给变量 attr_str
attr_str = ''.join(' %s="%s"' % (attr, value) for attr, value in sorted(attrs.items()))
else: # 如果 attrs 空的话,变量 attr_str 设置成空串
attr_str = ' '
if content: # 如果 content 参数非空的话,返回字符串:'<$name $attr_str>$content<$name>'
return '\n'.join('<%s%s>%s</%s>' % (name, attr_str, c, name) for c in content)
else:
return '<%s%s />' % (name, attr_str)
# print(tag('br'))
#
# print(tag('p', 'hello'))
#
# print(tag('p', 'hello', 'world'))
#
# print(tag('p', 'hello', id=33))
#
# print(tag('p', 'hello', 'world', cls='sidebar'))
#
# print(tag(content='testing', name='img'))
# 在 my_tag 前加上 **,该字典中的所有键值对都会作为一个单独的参数传入 tag() 中,
# 如果这些键值对中,有键名和 tag() 的参数列表中的参数名同名,那么该键值对的值赋给参数列表中对应的参数,
# 余下的键值对被 tag() 参数列表中的 **attrs 捕获为字典。
# 但是我自己加了一个 content 键名的键值对,content 没有接收到值,为什么?
# 如果传入的参数在 **my_tag 前面再加一个字符串,会报name有多个值的错误。
my_tag = {'name': 'img', 'content': 'wow~~', 'title': 'Sunset Boulevard', 'src': 'sunset.jpg', 'cls': 'framed'}
print(tag(**my_tag))