0
点赞
收藏
分享

微信扫一扫

大神教你五分钟搞清楚Python函数的参数!

关注涛哥聊Python

重磅干货,第一时间送达

大神教你五分钟搞清楚Python函数的参数!_python

灵活的参数

Python函数的形参种类多,且具有很高的灵活性。我们经常遇到:位置参数、关键词参数、仅限关键字参数、仅限位置参数等等。如果概念没彻底搞清楚,使用起来就不那么顺手。

提要:参数有 位置参数 和 关键字参数 两大类,分别都可以设置 默认值 ,也都可以设置 可变参数收集器 来分别收集两者。Python3新增了 仅限关键字参数 ,Python3.8新增了 仅限位置参数 。

大神教你五分钟搞清楚Python函数的参数!_html_02

上图概括了Python中的参数及其位置,这样在写程序的时候,我们能做到心中有数了。

本文以实际函数进化为例,逐个分析以上参数类型,最后囊括所有参数类型,以检验和加深理解。

现在,我们要编写一个HTML标签的生成函数。其调用形式:​​html = tag('p','Hello')​

可得html内容为:​​<p>Hello</p>​​。

仅使用位置参数就能实现这个功能。

位置参数

位置参数有普通位置参数、带默认值位置参数和可变参数收集器。如下用到前两者:

def tag(name,content='Nothing...'):
template = '<%s>%s</%s>'%(name,content,name)
return template

以上函数使用简单格式化字符串实现功能。其中name和content都是位置参数,实际调用的时候,可以灵活传入实参:


  • 忽略带默认值的参数 ​​tag('p')​
  • 顺序传入 ​​tag('p','Hello')​
  • 以命名方式乱序传入 ​​tag(content='Hello',name='p')​
  • 元组拆包传入参数 ​​tag(*('p','Hello'))​
  • 字典展开传入参数 ​​tag(**{'name':'p','content':'Hello'})​

可变参数收集

继续,我们需要根据多个内容,生成相同标签名的多个标签。例如​​html = tag('li','Line1','Line2','Line3')​​​要得到html内容为:​​<li >Line1</li><li >Line2</li><li >Line3</li>​​。

位置参数固定数目,而内容数目多变。为了实现收集多出来的'Line2'和'Line3',我们需要在位置参数列表的末尾,使用​​*args​​这种形式,定义可变参数收集,来收集剩余位置参数。所谓剩余元素,即实参传递给普通位置参数,覆盖默认值参数后的剩余参数。

def tag(name,content='Nothing...',*args):
template = '<%s>%s</%s>'%(name,content,name)
if args:
for arg in args:
template += '<%s>%s</%s>'%(name,arg,name)
return template

可变参数*args,收集name和content之外的剩余位置参数。

关键字参数

HTML标签可能需要许多属性,比如​​<a alt='Test URL' href='www.X.com'>X website</a>​​中的alt和href属性。这些属性需要明确指明变量名和具体值,关键字参数非常合用。

在位置参数列表的最后,使用​​**kwargs​​来收集关键字参数。

def tag(name,content='Nothing...',*args,**kwargs):
attrs = {}
if kwargs:
attrs.update(kwargs)
attrs = ' '.join(['%s=\'%s\''%(k,v) for k,v in attrs.items()])

template = '<%s %s>%s</%s>'%(name,attrs,content,name)
if args:
for arg in args:
template += '<%s %s>%s</%s>'%(name,attrs,arg,name)
return template

其调用形式为:​​html = tag('a','Hello',alt='test',href='http://www.baidu.com')'​​,得html内容为:Hello`

仅限关键字参数

新的需求:HTML标签需要定义style、class属性。而且是强制要求定义,在生成函数调用时,必须指出这两个属性,否则报错。这样的强制关键字参数的要求,用仅限关键字参数(keyword-only),非常符合要求。

仅限关键字参数定义在位置参数列表的末尾,关键字参数收集器之前。可以有默认值。主要特性是强制要求调用者以关键字形式传入参数。

其调用形式​​header = tag('p','Welcome to my website.',class_='p1',style='font-size:30')​​,调用中,明确指出了仅限关键字参数class_和style。函数定义如下,其使用attrs字典整合了两个仅限关键字参数和关键字参数收集器的内容:

def tag(name,content='Nothing...',*args,class_,style='color:000000',**kwargs):
attrs = {}
attrs['class'] = class_
attrs['style'] = style
if kwargs:
attrs.update(kwargs)
attrs = ' '.join(['%s=\'%s\''%(k,v) for k,v in attrs.items()])

template = '<%s %s>%s</%s>'%(name,attrs,content,name)
if args:
for arg in args:
template += '<%s %s>%s</%s>'%(name,attrs,arg,name)
return template

仅限位置参数

tag标签生成HTML中的前两个参数:name表示标签名,content表示标签内容。我们不希望这个参数乱用,或者各种拆包、展开字典赋值。只希望它变成​​pow(2,3),divmod(14,3)​​,这样意义非常明确的用法。以使调用tag时,明确第一个就是标签名,紧跟着标签内容。

实现这个功能,Python3.8新增的仅限位置参数(positional_only)非常适合。在仅限位置参数后加上一个/就实现了之前的参数是仅限位置参数的功能。

如下:

def
tag(name,content='Nothing...',/,*args,class_,style='color:
000000',**kwargs):

调用的时候,必须指出前两项,而且只能是按照位置传入,不能命名传入、元组拆包,字典展开等。这样的强制要求简化和规范了调用。

如下调用中,只有第一种符合仅限位置参数调用规范。

tag('p','content','content2',class_='flo')            #可行
tag(name='p',content = 'content','content2',class_='flo')
#失败

测试

使用如上述函数,我们实现了生成HTML标签内容的功能,整体测试如下:新建p,ul,li和a标签,封装进div,最后嵌入html中,生成index.html文件。

header = tag('p','Welcome to my website.',class_='p1',style='font-size:30')
intro = tag('p','gongqingkui M',class_='p1')

li = tag('li','Python Intro.','DIY CPU',class_='li1')
ul1 = tag('ul','Projects',li,class_='ul1')

homeURL = tag('a','X website',alt='Test URL',class_='a1',href='www.X.com',style='color:red')

main = tag('div',header,intro,ul1,homeURL,class_='main')
html = tag('html',tag('head','',class_=''),tag('body',main,class_=''),class_='')

with open('index.html','w',encoding='utf-8')as f:
f.write(html)

大神教你五分钟搞清楚Python函数的参数!_html_03源代码戳:https://gist.github.com/gongqingkui/5e4d1d8967a5eb47a1caee4eee3fc617

总结


  • 参数有 位置参数 和 关键字参数 两大类
    分别都可以设置 默认值
    也都可以设置 可变参数收集器 来分别收集两者
  • Python3新增了 仅限关键字参数
  • Python3.8新增了 仅限位置参数
  • 参数形式总结如下,函数def fun(a,b=2,/,c,d=4,*args,e,f=6,**kwargs)中:
    a 仅限位置参数
    b 带默认值的仅限位置参数
    c 位置参数
    d 带默认值的位置参数
    *args 位置参数收集器
    e 仅限关键字参数
    f 带默认值的仅限关键字参数
    **kwargs 关键字参数收集器

·················END·················

你好,我是Sitin涛哥,非著名程序员,项目经理,现在创业中。

公众号和视频号「涛哥聊Python」分享我的升级打怪经验!

很开心能够遇到你,欢迎添加我的微信  ,备注来意,一起进步。



举报

相关推荐

0 条评论