ladysosoli 2020-01-02
1.什么是函数
函数就好比一个盒子,它能封装了一段段逻辑代码,当我们需要重复使用这段逻辑代码,只需要调用这个函数即可,这样不仅仅实现了相同的功能,而且避免了重复造轮子,使得代码美观简洁。
2.为什么需要函数?
在开发的过程中,我们往往有成千上万行代码,而且其中还有很多行代码需要重复利用。为了提高代码的重复利用率和编写代码的整洁性,将代码封装在函数里面,使用的时候直接调用函数即可。总之函数的作用1.减少重复代码; 2.方便后期代码的维护更改; 3.保持代码的一致性(修改逻辑代码,后期的调用也会被改)。
3.函数的定义和调用
3.1 函数的定义
# 函数的定义 def myadd(num1, num2): # 函数头: def---关键字 myadd---函数名 num1,num2 参数 """ 这是一个计算两个数的和的函数 :param num1: 第一个 # 函数接口,类似于说明书,用来说明函数的作用,参数类型和返回值 :param num2: 第二个数 :return: 返回和 """ res = num1 + num2 # 函数体 :函数的功能块,业务逻辑 return res # 返回语句:将函数处理的结果返回给调用者 关键字return + 值 ,多个值用逗号隔开,如果没有返回语句,默认返回none
"""1. 当我们run一个函数的时候,操作系统将接口给cpu,cpu对硬盘下达指令,将函数从硬盘中调取到内存中;2. 在内存中,函数开始从上到下被执行;3. 首先到了def myadd这一个定义的步骤; (1)4. 内存就会给这个函数划拨一个空间,用于储存函数接口+函数体;5. 函数名myadd直接指向这个空间存储的内容;6. 以上步骤将函数存放到了内存中(函数真正实现功能并不在这步中,只有调用,这个函数才能实现他的功能)。这个定义步骤中,从上到下解释器只是检测代码的语法是否有问题,而不会去执行这个函数的内容比如:def test(): print(a)# 这里不去调用函数,从上到下检测代码语法,不会报错,但是我们知道这个a是没有定义的,但是并没有报错,总之这只是一个定义步骤"""3.2 函数的调用调用的格式为:函数名(参数)
# 函数的调用 a = myadd(3, 4) print(a) # 7
4.函数的参数
4.1 形参和实参
形式参数简称形参,在函数没有调用的时候,它没有任何意义,他必须传入参数,所以也叫必须参数
实际参数简称实参,在函数调用的时候传入,与定义函数的时候传入的形参一一对应, 所以它也叫位置参数
def sum(num1, num2, num3): num1,num2,num3是形式参数 result = num1 + num2 + num3 print(result)# 在函数调用的时候sum(12, 23, 34) #59 12, 23, 34就是实参,在这里,12赋值给了num1, 23赋值给了num2, 34赋值给了num3
4.2 默认参数
在我们定义参数的时候,我们给形参一个默认值,在我们调用函数的时候,如果不给有默认值的形参传入参数,那么这个参数就会采用默认值,当给默认参数传入了值,那么这传入的实参就会覆盖掉默认值
注意,当必须参数与默认参数同时使用的时候,默认参数都是放在必须参数后面
def info(name, age, gender="男"): print("姓名:{}, 性别:{}, 年龄:{}".format(name, gender, age)) print("name的实参是:", name) print("age的实参是:", age) print("gender的实参是:", gender) info1 = info("小李", 23) # 姓名:小李, 性别:男, 年龄:23 # name的实参是: 小李 # age的实参是: 23 # gender的实参是: 男 info2 = info("小梅", 22, "女") # 姓名:小梅, 性别:女, 年龄:22 # name的实参是: 小梅 # age的实参是: 22 # gender的实参是: 女
4.3 关键字参数
关键字参数是在调用的时候传入的,就是以键值对的方式对必须参数赋值
在之前我们都要求位置参数和必须参数是要一一对应的,但是关键字参数可以打破这种形式
def myadd(num1, num2, num3): res = num1 + num2 + num3 return res a = myadd(num2=12, num3=43, num1=1) print(a) # 56# 关键字参数和位置参数同时被使用的时候,关键字参数必须写在位置参数的后面
4.4 动态参数
动态参数接受的参数是不确定的,是动态的
# 动态参数 # def test(*args, **kwargs): """ * 是关键字,**是关键字 args, kwargs是变量名 当函数调用的时候,传入的所有多余的位置参数会组合成一个元组,被args接受 当函数调用的时候,传入的所有多余的关键字参数组合成一个字典,被kwargs接受 """ def test(*args, **kwargs): print(args) print(type(args)) print(kwargs) print(type(kwargs)) result = 0 for i in args: # result = i # 12748 print(i) result += i print(result) test(66, 88, 7374, a = 5, b = 8, c = 90) # (66, 88, 7374) # <class ‘tuple‘> # {‘a‘: 5, ‘b‘: 8, ‘c‘: 90} # <class ‘dict‘> # 66 # 88 # 7374 # 7528
几种参数的混合使用
1. 首先必须参数是放在最前面的
def test(a, *args, **kwargs): print(a, type(a)) # 66 <class ‘int‘> print(args, type(args)) # (88, 7374, 4, 5, 89) <class ‘tuple‘> print(kwargs, type(kwargs)) # {‘i‘: 5, ‘b‘: 8, ‘c‘: 90} <class ‘dict‘> test(66, 88, 7374, 4, 5, 89, i = 5, b = 8, c = 90)
2. 为动态参数传入列表、元组、字典
def test(*args, **kwargs): # print(args, type(args)) # (88, 7374, 4, 5, 89) <class ‘tuple‘> print(kwargs, type(kwargs)) # 传入列表 li = [1, 2, 3] test(li, 888) # ([1, 2, 3], 888) <class ‘tuple‘>, 将li作为一个整体传给args li = [1, 2, 3] test(*li, 888) # (1, 2, 3, 888) <class ‘tuple‘>, 将li解包成单个元素,再传给args # 元组类似 # 传入字典 di = {"k1": "v1", "k2": "v2", "k3": "v3"} test(2, di) # {} <class ‘dict‘> kwargs接收的是关键字参数,而di并不是一个关键字参数,他被作为一个整体传给了args test(2, di=di) # {‘di‘: {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘}} <class ‘dict‘> di=di作为一个关键字参数传入,而字典di的键值对作为一个整体传给了kwargs test(2, **di) # {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} <class ‘dict‘> 将di这个字典中的键值对解包,然后将里面的键值对一一传给kwargs
5. 几种常用的内置函数
# 列出全部内置函数 li = dir(__builtins__) print(li) print(len(li)) # 153 # 切片选出内置函数 li2 = li[li.index("abs"):] for i in li2: print(li2.index(i)+1, ">>>", i)
(1)enumerate 返回一个可以遍历的对象
# enumerate """ def __init__(self, iterable, start=0): # known special case of enumerate.__init__ Initialize self. See help(type(self)) for accurate signature. """ """ enumerate有2个参数,一个是可迭代对象,一个是start=0的默认参数 """ li = ["小明", "小米", "小亮"] print(li) # <enumerate object at 0x000002116E339638> 生成一个对象地址 print(list(enumerate(li))) # [(0, ‘小明‘), (1, ‘小米‘), (2, ‘小亮‘)] print(dict(enumerate(li))) # {0: ‘小明‘, 1: ‘小米‘, 2: ‘小亮‘} for i, j in enumerate(li, 1): print("第{}名,{}".format(i, j)) """ 第1名,小明 第2名,小米 第3名,小亮 """
(2) filter 过滤器
# filter() 过滤器 # filter(function=, iterable= ) 它的两个参数function是函数,iterable是可迭代对象 # 过滤,每个可迭代对象去执行函数,符合条件的留下,不符合被删去 def test(x): return x > 10 li = [1, 11, 2, 40, 8, 20] print(filter(test, li)) # <filter object at 0x000001310576EC08> print(list(filter(test, li))) # [11, 40, 20]
(3)map
# map 是对每一个可迭代对象去执行函数,是对数据对象的处理,将结果返回 # 它的两个参数有函数和可迭代对象 def func(num): return num * 10 li = [1, 2, 3] print(map(func, li)) # <map object at 0x0000021BBC221D88> print(list(map(func, li))) # [10, 20, 30]
(4) zip
# zip 将对象逐一地配对 l1 = ["k1", "k2", "k3"] l2 = ["v1", "v2", "v3"] print(zip(l1, l2)) # <zip object at 0x000001EAD16B1148> print(dict(zip(l1, l2))) # {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} print(list(zip(l1, l2))) # [(‘k1‘, ‘v1‘), (‘k2‘, ‘v2‘), (‘k3‘, ‘v3‘)]