> 文章列表 > Python基础-08 函数基础

Python基础-08 函数基础

Python基础-08 函数基础

什么是函数

  • 一堆准备好的代码,在需要的时候可以调用这一堆代码
  • 用重复的代码表示的缺点:冗余,可维护性差
  • 因此,将多行代码打包成一个整体:函数
  • 在Python中,用关键字 def 来声明一个函数
# def 函数名():
#   函数要执行的操作
  • 函数定义好之后并不会自动执行
  • 需要使用 函数名(参数) 来调用
  • 函数名也是一个标识符
  • 由数字,字母,下划线组成,不能以数字开头,严格区分大小写;不能使用关键字
  • 遵守命名规范,使用下划线连接;顾名思义:函数执行的逻辑,最好和函数的名字一致

函数的参数

  • 函数在声明的时候,括号里的参数我们称之为形式参数,简称形参
  • 形参的值是不确定的,只是用来占位的
  • 通过调用函数的时候,可以传递形参
  • 函数调用时候传入的参数,才是真正参与运算的数据,我们称之为实参
  • 函数调用时候,会把实参一一对应传递给形参处理
  • 也可以指定变量名,将实参传递给形参

函数的返回值

  • 返回值就是函数的执行结果,但是并不是所有的函数都必须要有返回值
def add(a,b):c = a+b  # 变量C在外部是不可见的,只能在函数内部使用return c  # return 表示一个函数的执行结果result = add(1,2)
print(result ** 4)
  • 如果一个函数没有返回值,就会返回None

函数的文档说明

  • 使用一对三个引号,在函数体中,表示函数的说明
def add(a,b):"""a: 第一个参数b: 第二个参数该函数返回两个数字相加的结果"""return a+b
  • 可以在编写函数的时候,在形参后面加上 :int 来指定希望传入的实参的类型
def add(a:int,b:str):  # 希望a的类型是int,b的类型是strpass

函数调用函数

  • 在函数2中,可以直接调用函数1,当函数2被调用的时候,会根据函数1在函数2代码中的位置,对函数1进行调用,演示如下:
def function_1():print('函数1开始了')print('函数1结束了')def function_2():print('函数2开始了')print('开始调用函数1')function_1()print('函数1调用结束')print('函数2结束了')function_2()# 函数2开始了
# 开始调用函数1
# 函数1开始了
# 函数1结束了
# 函数1调用结束
# 函数2结束了# 求m阶乘的和
def fac(n):x = 1for i in range(1,n+1):x *= ireturn xdef sum(m):x = 0for i in range(1,m+1):x += fac(i)return xprint(sum(5))

全局变量和局部变量

  • Python可以用函数来分隔作用域
  • 函数外部定义的变量是全局变量,在整个py文件中都可以访问
  • 函数内部定义的变量是局部变量,它是局部函数,只能在函数内部使用
  • 内置函数 globals() locals()可以打印函数中的全局变量和局部变量
a = 100  # a是全局变量
word = 'hello'def test():b = 80  # b是局部变量a = 10  print(a)# 如果在函数内部声明了一个与外部全局变量相同名称的变量,会新建一个函数内部的局部变量# 而不是修改外部的全局变量# 如果需要修改全局变量,可以使用global关键字global wordword = 'thank'print(word)print('locals = {},globals = {}'.format(locals(),globals()))  # ocals = {'b': 80, 'a': 10},globals = {'__name__': '__main_........ 全局变量非常多test()  # 10
print(a)  # 100print(word)  # thank

函数多个返回值

  • return表示一个函数的结束
  • 一般情况下,一个函数最多只会执行一个return语句
  • 特殊情况下(finally语句),下一个函数可能会执行多个return语句
def test(a,b):x = a // by = a % b# return x # return y# 以上代码只会执行一个return# return {'x':x,'y':y}  # 以字典的形式返回# return [x,y]  # 以列表的形式返回# return (x,y)  # 以元组的方式返回return x,y  # 返回的本质实际上就是返回一个元组print(test(12,5))  # (2, 2)

默认参数的使用

  • 有些函数的参数,如果你传递了参数,就是用传递的参数,如果没有传递参数,就使用默认的值
# print函数中,end就是一个缺省参数
print('hello',end = '')
print('你好')
# hello你好
  • 如何设定形参的默认值:在定义函数的时候,在需要默认值的形参处,直接给形参一个值
  • 如果没有传递参数,会使用默认值,如果传递参数,就使用传递的参数,如下
def say_hello(name,age,city='hangzhou'):print('大家好,我叫{},我今年{}岁了,我来自{}'.format(name,age,city))say_hello('lzh',18)  # 大家好,我叫lzh,我今年18岁了,我来自hangzhou
  • 可以直接传递单个参数,也可以使用变量赋值的形式传参
  • 如果有位置参数和关键字参数,关键字参数一定要放到位置参数的后面
def say_hello(name,age,city='hangzhou'):print('大家好,我叫{},我今年{}岁了,我来自{}'.format(name,age,city))say_hello(name ='lzh',city ='sichuan',age =18)  # 大家好,我叫lzh,我今年18岁了,我来自sichuan

可变参数的使用

  • 使用 *args 表示可变位置参数 --> 以元组的形式保存
  • 使用 **kwargs 表示可变关键字参数 --> 以字典的形式保存
def add (a,b,*args):  # args 表示可变参数,必须有两个参数pass
add(1,4,65,7,8,43)  # 多出来的可变参数会以元组的形式保存到args中def add(*args):  # 仅有可变参数passdef add(a,b,*args,mul=2):  # 如果有关键字参数,需要放在可变参数之后passdef add(a,b,*args,mul=2,**kwargs):  # 可以用 ** kwargs 来接受多余的关键字阐述pass

函数的注意事项

  • 函数的三要素
    • 函数名
    • 参数
    • 返回值
  • 有一些编程语言里,允许函数重名,在Python中不允许函数重名
  • 如果函数重名了,后一个函数会覆盖前一个函数
  • 在Python中,函数名也可以理解为一个变量名
  • 因此定义函数时,不要和内置函数重名

函数的递归

  • 递归简单的来说,就是函数内部自己调用自己
  • 递归最重要的就是要找到出口(停止的条件)
# 使用函数递归求1-n的和
x = 0
def get_sum(n):global xx += nn -= 1if n >= 1:get_sum(n)return xprint(get_sum(100)) # 5050# 递归方法2
def get_sum2(n):if n == 0:return nreturn n + get_sum2(n-1)print(get_sum2(100))  # 5050# 使用函数递归求n!
def get_num(n):if n == 0:return 1 return  n * get_num(n-1)print(get_num(0))  # 1# 斐波那契数列的第N个数字
def get_fi(n):if n == 2 or n == 1:return 1return get_fi(n-2) + get_fi(n-1)print(get_fi(8))  # 21

匿名函数

def add(a,b):return a+bx = add(1,2)  # 函数名(实参)作用是调用函数,获取到行数的执行结果并赋值给变量 xfn = add  # 相当于给函数add起了一个别名叫fn
  • 使用关键字 lambda 可以用来定义一个函数
  • 匿名函数,用来表达一个简单的函数
  • 如何调用一个匿名函数:
    • 第一种:给他定义一个名字(很少这样使用)
    • 第二种:把这个函数当做参数传给另一个函数使用
lambda a,b: a+b  
fn2 = lambda a,b: a+b  # 第一种调用方法def calc(a,b,fn):c= fn(a,b)return cx3 = calc(1,3,lambda x,y: x+y)  # 第二种调用方法:借用回调函数
print(x3)

sort方法的使用

  • 部分列表的内置函数和内置类,用到了内置函数
# 列表的 sort 内置方法会直接对列表进行排序
# sorted 内置函数,不会改变原有的数据,而是生成一个新的结果
students = [{'name':'zhoujielun','age':18,'sorce':97,'height':180},{'name':'linjunjie','age':22,'sorce':65,'height':177},{'name':'caiyilin','age':20,'sorce':88,'height':185}
]# 字典和字典之间不能使用比较运算
# students.sort()  # '<' not supported between instances of 'dict' and 'dict'# 需要传递一个 key 参数,指定比较的规则
# key 的参数类型是一个函数
# def foo(ele):
#     return ele['age']  # 在foo方法中,指定按照年龄进行排序# students.sort(key=foo)  
# 在sort方法中,会调用key中给定的函数,并且传入参数,参数是列表中的元素
# [{'name': 'zhoujielun', 'age': 18, 'sorce': 97, 'height': 180},
#  {'name': 'caiyilin', 'age': 20, 'sorce': 88, 'height': 185}, 
# {'name': 'linjunjie', 'age': 22, 'sorce': 65, 'height': 177}]# 简化sort函数
students.sort(key= lambda ele:ele['height'])
# [{'name': 'linjunjie', 'age': 22, 'sorce': 65, 'height': 177}, 
# {'name': 'zhoujielun', 'age': 18, 'sorce': 97, 'height': 180}, 
# {'name': 'caiyilin', 'age': 20, 'sorce': 88, 'height': 185}]print(students)

filter map reduce内置类的使用

  • filter 可以对可迭代对象进行过滤,得到的是一个filter对象
  • 在Python2中,是一个内置函数,在Python3中,修改成了一个内置类
# fliter 可以给定两个参数
# 第一个参数是一个函数
# 第二个参数是可迭代对象
# filter返回的结果是一个fiilter类型的对象
# filter对象本身也是一个可迭代的对象x = filter(lambda a: a%2 == 0,range(1,10))
print(x)  # <filter object at 0x0000024ED08E9FA0>
print(list(x))  # [2, 4, 6, 8]
for i in x:print(i,end='')  # 2468# map 内置方法,将可迭代对象中所有的元素按照map指定的方法处理
# 返回一个map类型的可迭代对象
ages = [10,11,25,16,8,14,46,547]m = map(lambda a: a+2,ages)
for x in m:print(x,end=' ')  # 12 13 27 18 10 16 48 549# reduce 以前是一个内置函数,现在在functools模块中
# 内置函数和内置类都在 builtin.py 文件中定义
from functools import reduce
def foo(x,y):return x + y scores = [100,154,1564,4684]print(reduce(foo,scores))  # 6502# 使用内置方法,求students中所有的age相加
from functools import reducestudents = [{'name':'zhoujielun','age':18,'sorce':97,'height':180},{'name':'linjunjie','age':22,'sorce':65,'height':177},{'name':'caiyilin','age':20,'sorce':88,'height':185}
]# 使用map函数先处理获取age,再使用reduce进行相加
print(reduce(lambda x1,x2:x1+x2,map(lambda a: a['age'],students)))  # 60# 或者直接给定reduce的初始值为0,那么第一轮运算时,给的第一个x的值就是0
print(reduce(lambda x1,x2:x1+x2['age'],students,0))  # 60