五、函数
1. 函数定义
函数就是将一些代码块封装到一个特定的容器内,只有需要使用该容器实现特定的功能时,才会通过调用函数的方式来运行其内部代码。
def fun(参数):
函数块
return 返回值
1.1 形参
定义函数时的参数。
- 位置参数
def fun(name, age, num):
pass
- 关键字参数
def fun(name = 'aaron', age = 20, num = '201620'):
pass
-
注意
- 位置参数和关键字参数混合使用时,位置参数必须在关键字参数之前。
def fun(name, age, num = '201620'): pass
- 对于函数的默认值谨慎使用可变类型。
# 如果想要给value设置默认值是空列表 # 不推荐 # 因为在建立函数时, 就已经创建了一个空列表. 在调用函数时, 若不传递value参数, 则调用的函数执行时, value指向同一个地址。 def func(data, value = []): pass # 推荐 def func(data, value = None): if not None: value = []
-
例子
# 方法一 def func(data, value = []): value.append(data) return value v = func(1) v1 = func(1,[11,22,33]) print(v) v2 = func(2) print(v,v1,v2) # 输出结果 [1] [1, 2] [11, 22, 33, 1] [1, 2]
# 方法二 def func(data, value = None): if not value: value = [] value.append(data) return value v = func(1) v1 = func(1,[11,22,33]) print(v) v2 = func(2) print(v,v1,v2) #输出结果 [1] [1] [11, 22, 33, 1] [2]
-
特殊的形参
def func(*args, **kwargs): pass # 其中*args用来接受除字典以外的其他类型的参数, **kwargs用来接受字典类型的参数
1.2 实参
调用函数时,传入的参数。
def fun(name, age, num):
pass
fun('aaron', 20, '201620')
-
注意
函数的参数传递的是内存地址(引用)。
1.3 返回值
谁调用了函数,函数的返回值就赋值给谁,当没指定返回值时,默认返回None。
def fun(name, age, num):
return name, age, num
-
注意
- 函数不被调用,函数内部的语句就不会被执行!!!
- 每次调用函数时,都会为此次调用开辟一块内存,内存可以保存自己以后想要用的值。
2. 匿名函数
-
定义
所谓的匿名函数就是没有函数名的函数,而是用lambda关键字来进行定义。
lambda x, y: x + y
- 上面的式子的功能等价于下面的函数。
def fun(x, y):
return x + y
3. 递归函数
- 自己调用自己的函数
def recursion():
num = input('请输入一个阿拉伯数字:')
if num.isdecimal():
print('输入成功')
else:
print('\n输入错误! 重新开始!\n')
recursion() # 在此处调用了自己
recursion()
4. 闭包
-
定义
为函数创建一个区域(内部变量供自己使用),为它以后执行提供数据。
name = 'oldboy'
def bar(name):
def inner():
print(name)
return inner
v1 = bar('alex') # {name = alex, inner} # 闭包
v2 = bar('eric')
v1()
v2()
-
例题
- 例子1
name = 'alex' def base(): print(name) def func(): name = 'eric' base() func() # 输出结果为 alex
- 例子2
info = [] def func(i): def inner(): print(i) return inner for item in range(10): info.append(func(item)) info[0]() info[1]() info[4]() # 输出结果为 0 1 4
- 例子3
name ='aaron' def fun(): def inner(): print(name) return inner() # 相当于 v = inner();return v inner无返回值,所以v = None, 调用fun()的返回值就为None # return inner # 若语句为左边所示,则最后的输出结果为inner函数所在的内存地址 r = fun() print(r)
-
注意
# 不是闭包 def bar(name): def inner(): return 123 return inner # 是闭包: 封装值 + 内层函数需要使用 def bar(name): def inner(): print(name) return 123 return inner
5. 内置函数
- 常用内置函数
id:# 查看地址值
type:# 查看类型
dir:# 获取当前数据内置的方法属性
len:# 求长度
range:# 生成一系列的数字
open:# 打开文件
input:# 输入
print:# 输出
help:# 帮助
'''
注意:关于上述提到的id是用来查看地址值的,这里补充一下is和==的区别。
is:用来判断两个变量的地址是否相同。
==:用来判断两个变量的值是否相同。
'''
-
高级内置函数
- map, 循环可迭代对象中的每个元素, 然后将每个元素执行函数, 将每次的执行的结果保存到一个迭代器中, 并返回。
“`python
格式:map(函数, 可迭代对象)
v1 = [1, 2, 3, 4, 5]
将v1中的每个元素都加10
result1 = map(lambda x: x + 10, v1)
将v1中的每个元素都乘10
result2 = map(lambda x: x * 10, v1)
print(result1)
result3 = []
for i in result1:
result3.append(i)
print(result3)
print(result2)
result4 = []
for i in result2:
result4.append(i)
print(result4)
# 输出结果
“`
- filter,循环可迭代对象中的每个元素, 然后将每个元素执行函数, 将每个满足函数条件的元素保存到一个迭代器中, 并返回。
# 格式:filter(函数, 可迭代对象)
v1 = [11, 22, 'aa', 33, 'bb']
# 求v1中类型为int的元素
result1 = filter(lambda x: type(x) == int, v1)
# 求v1中类型为str的元素
result2 = filter(lambda x: type(x) == str, v1)
print(result1)
result3 = []
for i in result1:
result3.append(i)
print(result3)
print(result2)
result4 = []
for i in result2:
result4.append(i)
print(result4)
# 输出结果
<filter object at 0x00000175EADDD048>
[11, 22, 33]
<filter object at 0x00000175EBE5CBA8>
['aa', 'bb']
-
注意
map和filter的返回值是一个迭代器,若直接输出,则得到的是一个地址值;对其进行for循环操作才能得到其值;或者直接用list()将迭代器强制转换成列表,可直接得到其值。
v1 = [11, 22, 'aa', 33, 'bb'] result = filter(lambda x: type(x) == int, v1) print(list(result)) # 输出结果 [11, 22, 33]
上述所说的是在Python3的版本下的执行结果;若是在Python2的版本下,map和filter的返回值将是一个列表。
-
reduce,可迭代对象中的元素循环执行函数,函数必须有两个形参,每次传入的两个参数中有一个是上一次执行得到的结果(只有第一次是传入第二个参数中的两个参数),将最终的结果保存到一个迭代器中,并返回。这是模块functools中的一个函数,将其放在此处是因为其使用方式和map、filter比较相似。
# 格式:reduce(函数, 可迭代对象)
from functools import reduce
v1 = [1, 10, 100, 1000]
# 求v1中元素的和
result1 = reduce(lambda x, y: x + y, v1)
# 求v1中元素的乘积
result2 = reduce(lambda x, y: x * y, v1)
print(result1)
print(result2)
# 输出结果
1111
1000000