1.函数基础
1.1 函数的定义及调用
1.1.1 函数的定义:
格式:
def 函数名(参数,.......):
代码
也可以不加参数
1.1.2 函数的调用
定义完函数后,此时函数还无法自动使用,需要我们人为调用才能使用。
格式:
函数名()
1.2 函数的参数
为了提升函数的通用性,引入了参数。比如 计算两个数的差,如果函数体定义了两个数的具体值,那么该函数只能计算这两个数的差。如果将具体的值换成参数,那么只需要在调用的时候赋予具体值,就可以实现计算多个两个数的差。
在定义函数的时候,小括号里写等待赋值的变量名,即形参
在调用函数的时候,小括号里写真正要进行运算的数据,即实参。
同时调用时在list或set,tuple前加* 表示拆包,在dict前加* ,拆key。在dict前加**,会拆成关键字参数的形式
函数的参数分为位置参数(a),关键字参数(a = 2),可变参数*args,可变关键字参数**kwargs
使用参数的顺序:位置参数,*args,默认值参数,**kwargs
1.2.1 定义带有位置参数的函数
def add2(a,b):
c = a+ b
print(c)
add2(1,2)
实现求任意两个数的和
1.2.2 定义带有默认值参数的函数
def add2 (a, b = 3): # b=3为默认值
c = a + b
print(c)
add2(6) # 9
add2() # 报错
add2(6,5) # 11
带有默认值的参数应该放在最后
调用函数时可以不给带有默认值的参数赋值,该参数的值即为默认值,也可以选择给其赋值,结果为调用时赋的值
1.2.3 定义带有可变位置参数的函数
求多个数的和:
def add(*b):
print(b) # 此时函数中可变的参数b是元组类型的
if len(b) >= 2:
total = 0
for i in b:
total += i
print('累加和是:', total)
else:
print('提供的参数不足')
add(3, 4, 5) # (3, 4, 5)
累加和是: 12
add() # ()
提供的参数不足
add(1, 2) # (1, 2)
累加和是: 3
add(1, 2, 3, 4, 5, 6, 7) # (1, 2, 3, 4, 5, 6, 7)
累加和是: 28
可以实现求任意个数的和
1.2.4 定义带有可变关键字参数的函数
def show_friend(name, **kwargs):
if len(kwargs) > 0:
print(kwargs) # kwargs为字典类型的变量
print('{}的朋友有如下特征:'.format(name))
for key,value in kwargs.items():
print('{}:{}'.format(key,value))
else:
print('没朋友')
1.2.5 定义默认值参数和可变未知参数混合的函数
def func01(*args, sep=' ', name='张三'):
if len(args) > 0:
print(name + '正在进行拼接中...')
result = sep.join(args)
print(result)
else:
print('没有任何拼接内容!')
func01('hello', 'hi', '喂') # 张三正在进行拼接中...
# hello hi 喂
func01('hello', 'hi', '喂', name='李四') # 李四正在进行拼接中...
# hello hi 喂
默认值参数应该放在可变位置参数的后面
1.3 函数的返回值
所谓“返回值”,就是程序中函数完成一件事情后,最后给调用者的结果
使用返回值的前提需求就是函数调用者想要在函数外使用计算结果
函数利用return 关键字,将函数的结果返回给调用者,如果调用者想要使用这个数据,那就需要使用一个变量来保存函数返回的结果
return可以加多个变量,但会自动将所有变量装成元组类型
return标志着函数执行结束
1.4 函数的嵌套
一个函数的函数体中又调用了别的函数,即为函数的嵌套
1.5 函数的文档注释
2.函数高级
2.1全局变量与局部变量
2.1.1 局部变量
局部变量,就是在函数内部定义的变量
其作用范围是这个函数内部,即只能在这个函数中使用,在函数的外部是不能使用的
因为其作用范围只是在自己的函数内部,所以不同的函数可以定义相同名字的局部变量(打个比方,把你、我是当做成函数,把局部变量理解为每个人手里的手机,你可有个iPhone8,我当然也可以有个iPhone8了, 互不相关)
局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储
当函数调用时,局部变量被创建,当函数调用完成后这个变量就不能够使用了
2.1.2 全局变量
在函数外部定义的变量就为全局变量,它能被所有函数所使用
在函数内部修改全局变量,如果该变量是不可变类型需要加global,如果是可变类型则不需要加。可以同时声明多个全局变量,用,隔开。
当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值
如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据也理解为对全局变量进行修改,而不是定义局部变量
Python提供了两个内置函数globals()和locals()可以用来查看所有的全局变量和局部变量,默认以字典类型返回。但是要主要他们使用的位置。
函数中变量的访问顺序:函数自身,全局,builtings,最后找不到报错
2.2 内部函数
内部函数:在一个函数的内部重新定义一个新函数,其即为内部函数
特点:
内部函数在外部函数的里面
内部函数可以访问外部函数的变量
内部函数不可以修改外部函数的变量,除非添加nonlocal关键字来声明变量
内部函数变量的使用顺序:内部函数自身的,外部函数的,全局变量,butings,报错。
2.3 闭包
闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数块+引用环境)
特点:
外部函数中定义了内部函数
内部函数使用了外部函数的变量
外部函数的返回值是内部函数
闭包里默认不能修改外部变量。除非添加nonlocal关键字声明变量
2.4 装饰器
装饰器也是一个特殊的函数,即闭包函数,使用时需要@+函数名。
装饰器的使用场景:
它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
装饰器的基本格式:
def deco(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
msecs = (end_time - start_time) * 1000
print('执行时间为{}'.format(msecs) )
return wrapper
@deco
def test():
print('计算本段代码的执行时间')
time.sleep(1)
print('计算本段代码的执行时间')
test()
以上述代码为例,装饰器的执行过程:
1.首先将装饰器函数deco,要装饰的函数test加载进内存
2.然后找装饰器函数deco,同时func接收被装饰的函数test
3.执行deco函数,执行完成后,被装饰函数test接收deco函数的返回值warpper
此时 test = wrapper
3. 函数
3.1 递归函数
在函数自身的函数体调用自己,并且有结束条件。
例:求1-5的和
def func(n):
if n < 10:
# 累加
return func(n + 1) + n
else:
# 结束
return n
print(func(1))
3.2 匿名函数
可以简化编程,一种轻量级函数。常与高阶函数结合使用。
格式:
lambda 参数列表: 运算表达式
Lambda函数能接收任何数量的参数但只能返回一个表达式的值
匿名函数可以执行任意表达式(甚至print函数),但是一般认为表达式应该有一个计算结果供返回使用。
python在编写一些执行脚本的时候可以使用lambda,这样可以接受定义函数的过程,比如写一个简单的脚本管理服务器。
应用场合
>>> def fun(a, b, opt):
... print("a = " % a)
... print("b = " % b)
... print("result =" % opt(a, b))
...
>>> add = lambda x,y:x+y
>>> fun(1, 2, add) # 把 add 作为实参传递
a = 1
b = 2
result = 3
3.3 高阶函数
python中函数也是一种复杂的数据类型
我们可以使用一个变量来指向函数,相当于给函数起了一个别名,两者地址相同,但是要注意不能加括号,否则表示调用这个函数。
3.3.1定义:
高阶函数:既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,同样,我们还可以把一个函数当做另一个函数的返回值。这种函数的使用方式我们称之为高阶函数。
python中使用参数为函数的内置函数和类:
sorted函数: 以指定方式进行排序
l = [('张三', 21, 100), ('李四', 19, 60), ('王五', 20, 86)]
result = sorted(l, key=lambda s: s[2])
print(result)
dict1 = {'张三': 50, '李四': 20, '王五': 30}
result = sorted(dict1.items(),key=lambda dict:dict[1] )
print(result)
print(dict(result))
students =[
{'name':'tom','age':20},
{'name':'lucy','age':19},
{'name':'lily','age':13},
{'name':'mark','age':21},
{'name':'jack','age':23},
{'name':'steven','age':18},
]
s = sorted(students, key=lambda d: d['age']) # 以age排序
print(s)
filter函数:以指定条件过滤列表元素
students =[
{'name':'tom','age':20},
{'name':'lucy','age':19},
{'name':'lily','age':13},
{'name':'mark','age':21},
{'name':'jack','age':23},
{'name':'steven','age':18},
]
r = filter(lambda s:s['age']>20,students)
print(list(r)) # 筛选age大于20的学生
map函数::对列表中每个元素执行相同操作
l = [1,3,6,6]
m = map(lambda x:x+5,l)
print(list(m)) # l中每个元素加5
list2 = [('张三', 21, 100), ('李四', 19, 50), ('王五', 20, 46), ('赵柳', 25, 60)]
m = map(lambda s: (s[0], s[1], s[2] + 10) if s[2] < 60 else s, list2)
print(list(m)) # [('张三', 21, 100), ('李四', 19, 60), ('王五', 20, 56), ('赵柳', 25, 60)]