python基础第十二课--函数高级特性,值得一看(小白piao分享)

#编写可接受任意数量参数的函数
#我们想要去编写一个可以接受任意数量参数的函数

#解决方案:
#要想编写一个可接受任意数量位置参数的函数,可以使用以*开头的参数
def avg(first,*rest):
return ((first+sum(rest)) / (1 + len(rest)))

print(avg(1,2))#1.5
print(avg(1,2,3,4))#2.5

#rest 是一个元组,它包含了所有传递过来的位置参数;代码在之后的计算中会将其视为一个序列来处理
#如果要接受任意数量的关键字参数,可以使用以**开头的参数:
import html
def make_element(name,value,**kwargs):
key_values = [’%s="%s"’% item for item in kwargs.items()]
kwarg_str = ’ '.join(key_values)
ele = ‘<{name} {attrs}>{value}</{name}>’.format(name=name,attrs=kwarg_str,value=html.escape(value))
return ele

str1 = make_element(‘item’,‘Albatatross’,size=‘large’,quantity=6)
print(str1)#Albatatross
str2 = make_element(‘p’,’’)
print(str2)#

<spam>

#这里的kwargs是一个字典,它包含了所有传过来的关键字参数(可有可无)
#如果想要函数同事接受任意数量的位置参数和关键字参数,只要联合使用*和**即可。

#在函数定义中,以打头的参数只能作为最后一个位置参数出现,而以**打头的参数只能作为最后一个参数出现。
#在
的后边仍然可以有其他参数出现,这样的参数叫做keyword-only参数

#定义带有默认参数的函数;
#我们想去定义一个带有可选参数的函数是非常简单的–只需要在定义中为参数复制,并确保默认参数出现在最后即可。
#如果默认值是可变容器的话,比如说列表,集合或者字典,那么应该把None作为默认值
#注意:对默认参数的赋值,只会在函数定义的时候绑定一次!!!!;其次对默认参数的赋值总是不可变的对象
# (比如None,True,False,字符串,数字)
#总之不要这样编写代码:
def func(a,lt=[]):
print(lt)
return lt
x = func(1)#[]
print(x)#[]
x.append(99)
x.append(‘yow!yow!qeknow’)
func(2)#[99, ‘yow!yow!qeknow’] 最终会导致默认参数的值持续被修改!!!

a = …
print(a,type(a))#Ellipsis <class ‘ellipsis’>

#在回调函数中携带额外的状态
#我们正在编写需要使用回调函数的代码,但是希望回调函数可以携带额外的状态以便在回调函数内部使用

#解决方案:
#定义如下函数,会调用一个回调函数:
#应该把所有注意力集中在回调函数的调用上
def funcCallBack(func,args,*,callback):
res = func(*args)
callback(res)

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

def my_print(res):
print(‘result={}’.format(res))

funcCallBack(add,(1,2),callback=my_print)#result=3

#一种在回调函数中携带额外信息的方法是使用绑定方法(bound-method);而不是普通的函数
#例如下方这个例子,在每次调用时,会打印调用回调函数的次数:

class CallBackFuncClass():
def init(self):
self.count = 0
def handler(self,result):
self.count += 1
print(’[{}],result = {}’.format(self.count,result))
r = CallBackFuncClass()

for x in range(3):
funcCallBack(add,(2,3),callback=r.handler)
#[1],result = 5
#[2],result = 5
#[3],result = 5

#作为类的替换方案,可以使用函数的内部定义来完成
def CallBackFuncClass():
count = 0
def handler(result):
nonlocal count
count += 1
print("{},result = {}".format(count,result))
return handler

handler = CallBackFuncClass()

funcCallBack(add,(2,3),callback=handler)#1,result = 5
funcCallBack(add,(2,3),callback=CallBackFuncClass())#1,result = 5

#最后但也同样重要的是,也可以通过额外的参数在回调函数中携带状态,然后用partial()来处理参数个数问题

class Seq():
def init(self):
self.sequence = 0

def handler(res,seq:Seq):
seq.sequence += 1
print("{} res: {}".format(seq.sequence,res))

import functools as f
seq = Seq()
funcCallBack(add,(2,3),callback=f.partial(handler,seq = seq))#1 res: 5

#访问定义在闭包内部的变量
#我们希望通过函数来扩展闭包,使得在闭包内层定义的变量可以被访问和修改

#解决方案:
#要注意在闭包内层的变量对于外界来说完全是隔离的。
#可以通过编写存取函数并将它们作为函数属性附加到闭包上来提供对内层变量的访问支持

def sample():
n = 0
def func():
print(‘n:’,n)
def get_n():
return n
def set_n(value):
nonlocal n
n = value

func.get_n = get_n
func.set_n = set_n
return  func

f = sample()
f()#n: 0
f.set_n(10)
f()#n: 10
print(f.get_n())#10

发布了17 篇原创文章 · 获赞 1 · 访问量 353

猜你喜欢

转载自blog.csdn.net/weixin_43520503/article/details/104557654