可接受任意数量参数的函数
def anyargs(*args,**kwarges):
-
其中有三种类型
- 强制关键字参数
def recv(maxsize, * , block): \#sample recv(1024, block=True)
- 接受任意数量的位置参数:
def avg(first,*rest): \# Sample use avg(1, 2) # 1.5 avg(1, 2, 3, 4) # 2.5
- 接受任意数量的关键字参数 :
def make_element(name, value, **attrs): \# Example make_element('item', 'Albatross', size='large', quantity=6) make_element('p', '<spam>')
-
给函数参数添加元信息也就是添加注释
def add(x:int, y:int) -> int: return x + y
定义匿名或内联函数
- lambda函数:见前面的笔记
将单方法的类转换为函数【重要】
问题:有一个除 __init__()
方法外只定义了一个方法的类,为了简化代码需转换为一个函数;
-
闭包
from urllib.request import urlopen class UrlTemplate: def __init__(self, template): self.template = template def open(self, **kwargs): return urlopen(self.template.format_map(kwargs)) # Example use. Download stock data from yahoo yahoo = UrlTemplate('http://finance.yahoo.com/d/quotes.csv?s={names}&f={fields}') for line in yahoo.open(names='IBM,AAPL,FB', fields='sl1c1v'): print(line.decode('utf-8'))
可以写成这种***[重点]***
def urltemplate(template): def opener(**kwargs): return urlopen(template.format_map(kwargs)) return opener # Example use yahoo = urltemplate('http://finance.yahoo.com/d/quotes.csv?s={names}&f={fields}') for line in yahoo(names='IBM,AAPL,FB', fields='sl1c1v'):#注意这里没有open() print(line.decode('utf-8'))
解释:
拥有一个方法类的原因是需要存储某些额外的状态来给方法使用,比如,定义UrlTemplate 类的唯一目的就是先在某个地方存储模板值,以便将来可以在open() 方法中使用。
简单来讲,一个闭包就是一个函数,只不过在函数内部带上了一个额外的变量环境。闭包关键特点就是它会记住自己被定义时的环境。因此,在我们的解决方案中,opener() 函数记住了template参数的值,并在接下来的调用中使用它–自动调用
-
访问闭包中定义的变量
关于nonlocal 声明https://blog.csdn.net/xcyansun/article/details/79672634 这里讲得比较好;
总结:global更改的是全局变量,nonlocal更改的是上层函数里的变量。在不修改的情况下,就近原则,若上层函数有就访问上层函数的,否则就访问全局的。
1)任何一层子函数,若直接使用全局变量且不对其改变的话,则共享全局变量的值;一旦子函数中改变该同名变量,则其降为该子函数所属的局部变量;
2)global可以用于任何地方,声明变量为全局变量(声明时,不能同时赋值);声明后再修改,则修改了全局变量的值;
3)而nonlocal的作用范围仅对于所在子函数的上一层函数中拥有的局部变量,必须在上层函数中已经定义过,且非全局变量,否则报错。(这句话理解https://www.cnblogs.com/liyang93/p/6669874.html