02 - 函数与装饰器
Posted liulyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02 - 函数与装饰器相关的知识,希望对你有一定的参考价值。
函数与装饰器
函数
概念
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数的返回值
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
# return a,b,c等价于 return (a,b,c) def test(): a,b = 10,20 return a,b print(test())
不定长参数传递
加了星号(*)的变量args会存放所有未命名的变量参数,args为元组;
而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典。
def function(a,b,*args,**kwargs):#装箱 print(a,b) print(args)#元组存放 print(kwargs)#字典存放 A = (33,44,55) B = {"name":"jerry","age":6} function(11,22,*A,**B) #拆包元组和字典
全局变量
在python中,创建变量时默认是定义新的变量(局部变量),除非显式声明global。
对于不可变对象(数值,字符串,元祖)的全局变量来说,因其指向的数据不能修改,所以不使用global时无法修改全局变量。
a = 1 def f(): a += 1 # a = a+1,默认局部变量,变量a没有指向,就被引用计算,故报错 print(a) f() UnboundLocalError: local variable ‘a‘ referenced before assignment
对于可变对象(比如list和dictionary)的全局变量来说,因其指向的数据可以修改,所以不使用global时也可修改全局变量。
a = [1,2,3] def f(): a.append(4) # 对可变对象的全局变量a的操作,id相同 f() print(a) #结果:[1, 2, 3, 4]
函数传递参数类型
函数传递参数类型,引用传递or值传递。
"""对变量赋值时的地址变化""" a = [1,2,3] b = [1,2,3] c = 1 d = 1 print(id(a)) #2190918037640 print(id(b)) #2190920543560 print(id(c)) #1929604576 多个变量会指向同一个地址 print(id(d)) #1929604576
实例1
a = 1 print(id(a)) #1929604576 def function(b): print(id(b)) #1929604576 引用传递,指向关系相同 b += 1 #判断变量b是否可修改,不是则默认执行b = b+1 print(b) #2 print(id(b)) #1929604608 变量b改变指向(不可变对象) function(a) print(a) #1
实例2
a = [1,2,3] a = [1,2,3] def function(b): def function(b): b = b+[4] b += [4] #和b.append(4)结果相同 print(b) print(b) function(a) function(a) print(a) print(a) #结果:[1, 2, 3, 4] 结果:[1, 2, 3, 4] # [1, 2, 3] [1, 2, 3, 4]
总结:赋值相当于变量指向了新的地址(+=除外), 在python中,不可变对象是共享的,创建可变对象永远是分配新地址。
缺省参数
注意:带有默认值的参数一定要位于参数列表的最后面。
def test(a,b=12,c=20): pass test(10,c=10) #默认b=12,test(10,12,10)
默认参数的坑
def func(x,l=list()): for i in range(x): l.append(i*2) print(l) func(2) #[0, 2] func(3,[1,2,3]) #[1, 2, 3, 0, 2, 4] func(3) #[0, 2, 0, 2, 4] func(4) #[0, 2, 0, 2, 4, 0, 2, 4, 6] func(3,[1,2,3]) #[1, 2, 3, 0, 2, 4]
匿名函数
语法:变量 = lambda 参数:返回值
ls = lambda x:x+2 print(ls(5)) #结果:7
内置函数:eval()将字符串str当成有效的表达式来求值并返回计算结果。
def test(a,b,fun): return fun(a,b) #匿名函数的调用 lamb = input("请输入匿名函数:") test(10,20,eval(lamb)) #eval()原样输出 #请输入匿名函数: lambda x,y:x+y #结果:30
匿名函数的应用
# 取出最大工资对应的人名 salaries = { ‘qiu‘: 2000, ‘xi‘: 30000, ‘qiuxi‘: 2500, ‘rufeng‘: 3000 } def func(k): return salaries[k] print(max(salaries,key=func)) # xi # 1. 将可迭代对象salaries变成迭代器对象iter_obj # 2. next(iter_obj)得到一个人名,然后将该人名当作参数传给key指定的函数,然后调用函数将函数的返回值当作比较依据 # 3. 比较大小,取出最大值对应的人名 # 上面的函数还可以用匿名函数来实现 print(max(salaries, key=lambda k: salaries[k])) # 同样,取出最小的使用函数min print(min(salaries, key=lambda k: salaries[k]))
内置函数:sorted(),排序并返回新的值
a = {k1:v1,k2:v2} # 从大到小 print(sorted(salaries, key=lambda k: a[k], reverse=True)) # 从小到大 print(sorted(salaries, key=lambda k: a[k]))
内置函数:map()提供的函数对指定序列做映射。
map(function, iterable, ...)
name = [a,b,c,d] # 列表生成式 new_names = [name+‘_1‘ for name in names] print(new_names) # map+匿名函数 res = map(lambda x: x+‘_1‘, names) print(res) #打印函数地址 print(list(res))
functools模块函数 :reduce()对参数序列中元素进行累积。
reduce(function, iterable[, initializer])
from functools import reduce reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数 #结果:15
内置函数:filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
filter(function, iterable)
a = [1,2,3,4,5,6,7,8] b = filter(lambda x:x%2==0,a) #满足函数条件的留下,即返回值是True,b为迭代器对象 print(list(b))
以上是关于02 - 函数与装饰器的主要内容,如果未能解决你的问题,请参考以下文章
python-闭包和装饰器-02-装饰器(decorator)