一、函数的定义
函数是:
- 将一件事情的步骤封装在一起并得到最终结果
- 函数名代表了这个函数要做的事情
- 函数体是实现函数功能的流程
- 方法或者功能
- 可以重复利用
函数分为内置函数和自定义函数,在前面提到的各个数据类型能调用的方法都是内置函数,当内置函数无法满足我们的需求时,就需要进行自定义函数。
Python中通过关键字def来定义函数
def func_name(args..) todo 返回值 复制代码
通过 函数名()
的形式来执行函数或者调用函数
函数结果的返回:
- return 是函数结果返回的关键字
- return 只能在函数体内使用
- return 支持返回所有的 Python 数据类型
- 有返回值的函数可以将返回值直接赋值给一个变量
自定义一个 capitalize 函数
def capitalize(data): index = 0 # 保存新字符串 temp = '' for item in data: # 第一次循环获取到第一个字符 if index == 0: temp = item.upper() else: temp += item index += 1 return temp res = capitalize('hello') print(res) 复制代码
res = capitalize(123) print(res) 复制代码
定义一个无返回值的函数
def message(mes, mes_type): new_mes = '[%s]%s' % (mes_type, mes) print(new_mes) message('I am IronMan', 'info') 复制代码
函数返回的结果为 None
res = message('Tomorrow is Friday', 'info') print('res:%s' % res) 复制代码
return 与 print 的区别:
- print只是单纯的将对象打印,不支持赋值语句
- return是对函数执行结果的返回,也支持赋值语句
二、函数的参数
函数的参数有必传参数、默认参数以及不确定参数。
必传参数与默认参数
函数中定义的参数没有默认值,在调用函数时如果不传则报错。
必传参数有以下特点
- 函数中没有默认值,不传会报错
- 定义函数时,参数后面没有等号进行赋值
- 在定义函数的时候,没有默认值且必须在函数执行的时候传递进去的参数,且顺序与参数顺序相同,就是必传参数
在定义函数的时候,定义的参数含有默认值,通过赋值语句给参数一个默认的值,如果默认参数在调用函数的时候给予了新的值,函数将优先使用后传入的值。
def add(a, b, c=3): return a + b + c result = add(1, 2) print(result) result = add(1, 2, 6) print(result) result = add() print(result) 复制代码
不确定参数
不确定参数也就是可变参数:
- 没有固定的参数名和数量,不确定传递的参数名,不确定传递的参数个数
- *args代表将不定个数的参数合并成元组
- **kwargs表示将有参数与默认值的语句合并成一个字典
def alpha(*args, **kwargs): print(args, type(args)) print(kwargs, type(kwargs)) alpha(1, 2, 3, name='stark', address='NY') 复制代码
def bravo(*args, **kwargs): if len(args) > 0: for i in args: print(i) if 'name' in kwargs: print(kwargs['name']) bravo('stark', 'peter', 'banner', 'clint', name='小明', address='上海') 复制代码
传递元组和字典类型参数
tuple_01 = (1,3,5,8,0,11) dict_01 = {'name': 'stark', 'address':'NY'} bravo(tuple_01, dict_01) bravo(*tuple_01, **dict_01) 复制代码
参数规则
def alpha(x, y = 1): print(x + y) # 使用位置传参 alpha(1, 2) # 位置传参,只传必填参数 alpha(1) # 使用关键字传参 alpha(x = 1, y = 2) # 关键字传参,只传必填参数 alpha(x = 1) # 关键字传参,不必遵循参数先后顺序 alpha(y = 1, x = 2) 复制代码
必填参数一定要传,否则会报错
def bravo(x, y=1, *args): print('x={}, y={}, args={}'.format(x, y, args)) tuple_01 = (1, 2) bravo(1, 2, *tuple_01) # 这种传参方式会报错 bravo(x=1, y=2, *tuple_01) 复制代码
当必传参数与默认参数与元组类型参数混用时,推荐使用位置传参
def charlie(x, y=1, **kwargs): print('x={}, y={}, kwargs={}'.format(x, y, kwargs)) dict_01 = {'name': 'stark', 'address': 'NY'} charlie(1, 2, **dict_01) # 这种传参方式会报错, 位置传参字典必须放到最后 # charlie(**dict_01, 1, 2) charlie(x=1, y=2, name='stark', address='NY') charlie(name='stark', address='NY', x=1, y=2) 复制代码
def delta(x, y=1, **kwargs): print('x={}, y={}, kwargs={}'.format(x, y, **kwargs)) dict_01 = {'name': 'stark', 'address': 'NY'} delta(1, 2, **dict_01) 复制代码
函数体内不能加*或者**
函数参数的类型
可以对函数参数的类型进行定义,定义方式如下
- 通过参数名:参数数据类型的方式定义参数类型
- Python 3.7 以后的版本才可以使用
- 不会对参数类型进行校验
def foxtrot(x:str, y:int=1): print('x={}, y={}'.format(x, y)) foxtrot('stark') foxtrot('stark', 2) foxtrot(1, 'stark') 复制代码
def golf(x:str, y:int=1, *args:int, **kwargs:str): print('x={}, y={}, args={}, kwargs={}'.format(x, y, args, kwargs)) golf('stark', 2, 1, 2, name='stark') golf(1, 3, 2, 3, id=1) 复制代码
三、全局变量与局部变量
全局变量定义在Python脚本最上层代码块的变量,全局变量在函数体内可以读取,但是无法在函数体内进行修改
name = 'stark' def hotel(): print('函数体内打印出name的值为:', name) hotel() print('函数体外打印出name的值为:', name) 复制代码
在函数体内定义的变量称为局部变量,局部变量只能在当前定义的函数体内使用,函数体外无法使用
def iris(): address = 'New York' print('函数体内使用局部变量:',address) iris() print('函数体外使用局部变量:', address) 复制代码
使用global关键字可以将全局变量在函数体内修改。
name = 'stark' print('函数体外打印出修改前name的值为:', name) def hotel(): global name name = 'tony stark' print('函数体内修改name的值为:', name) hotel() print('函数体外再次打印出name的值为:', name) 复制代码
global 只支持数字字符串和空类型以及布尔类型,字典列表在函数体类修改是不需要 global 关键字的,不建议在函数体内使用 global 关键字修改全局变量
四、递归函数
一个函数不停的将自己反复执行,可以称之为递归函数。
count = 0 def juliet(): global count count += 1 if count != 5: print('count!=5时重复执行自己,当前count为:', count) return juliet() else: print('count:',count) juliet() 复制代码
递归函数如果没有退出递归的条件会导致内存溢出。
五、匿名函数
lambda 可以定义一个轻量化的函数,即用即删除,很适合需要完成一项功能,但只在一处使用的情况
无参数匿名函数的定义方法
f = lambda: value f() 复制代码
有参数匿名函数的定义方法
f = lambda x, y: x + y f(1, 2) 复制代码
kilo = lambda: 1 res = kilo() print(res) 复制代码
lambda 冒号后面的内容就是返回的内容,默认省略了 return 关键字,如果加上 return 关键字会报错
lima = lambda : print('I am IronMan') lima() 复制代码
mike = lambda x, y: x * y print(mike(9, 8)) 复制代码