当前位置: 首页 > article >正文

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的类型是str
    pass

函数调用函数

  • 在函数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 = 1
    for i in range(1,n+1):
        x *= i
    return x

def sum(m):
    x = 0
    for i in range(1,m+1):
        x += fac(i)
    
    return x

print(sum(5))

全局变量和局部变量

  • Python可以用函数来分隔作用域
  • 函数外部定义的变量是全局变量,在整个py文件中都可以访问
  • 函数内部定义的变量是局部变量,它是局部函数,只能在函数内部使用
  • 内置函数 globals() locals()可以打印函数中的全局变量和局部变量
a = 100  # a是全局变量
word = 'hello'

def test():
    b = 80  # b是局部变量
    a = 10  
    print(a)
    # 如果在函数内部声明了一个与外部全局变量相同名称的变量,会新建一个函数内部的局部变量
    # 而不是修改外部的全局变量
    # 如果需要修改全局变量,可以使用global关键字
    global word
    word = 'thank'
    print(word)
    print('locals = {},globals = {}'.format(locals(),globals()))  # ocals = {'b': 80, 'a': 10},globals = {'__name__': '__main_........ 全局变量非常多

test()  # 10
print(a)  # 100

print(word)  # thank

函数多个返回值

  • return表示一个函数的结束
  • 一般情况下,一个函数最多只会执行一个return语句
  • 特殊情况下(finally语句),下一个函数可能会执行多个return语句
def test(a,b):
    x = a // b
    y = 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):  # 仅有可变参数
    pass

def add(a,b,*args,mul=2):  # 如果有关键字参数,需要放在可变参数之后
    pass

def add(a,b,*args,mul=2,**kwargs):  # 可以用 ** kwargs 来接受多余的关键字阐述
    pass

函数的注意事项

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

函数的递归

  • 递归简单的来说,就是函数内部自己调用自己
  • 递归最重要的就是要找到出口(停止的条件)
# 使用函数递归求1-n的和
x = 0
def get_sum(n):
    global x
    x += n
    n -= 1
    if n >= 1:
        get_sum(n)
    return x

print(get_sum(100)) # 5050

# 递归方法2
def get_sum2(n):
    if n == 0:
        return n
    return 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 1
    return get_fi(n-2) + get_fi(n-1)

print(get_fi(8))  # 21

匿名函数

def add(a,b):
    return a+b

x = add(1,2)  # 函数名(实参)作用是调用函数,获取到行数的执行结果并赋值给变量 x

fn = 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 c

x3 = 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 reduce

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}
]

# 使用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

http://www.kler.cn/a/11688.html

相关文章:

  • 相亲小程序(源码+文档+部署+讲解)
  • 大数据新视界 -- 大数据大厂之 Impala 性能优化:优化数据加载的实战技巧(下)(16/30)
  • FMC 扩展子卡6 路 422,8 组 LVDS,8 路 GPIO
  • GFPS技术原理(四)GATT特征值
  • SwiftUI开发教程系列 - 第1章:简介与环境配置
  • 【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
  • Python-代码阅读(1)-funcs.py
  • 00.如何学习spring
  • Dapper——分布式跟踪系统
  • JavaScript基础05 - JSON
  • Node fs模块
  • 一个lapack网页 dstedc DSYTRD cusolverDnCheevd
  • Java开发 - 公共字段的自动填充
  • 第十四天本地锁、Redis分布锁、Redisson锁三者的区别
  • 什么是MVVM?
  • Kafka是如何支持百万级TPS的?
  • Pandas2.0它来了,这些新功能你知道多少?
  • 冥想第七十六十三天
  • 使用Go语言打造轻量级Web框架
  • 【学习笔记】Linux基础
  • 【排序】【二分】【角度制】个人练习-Leetcode-1610. Maximum Number of Visible Points
  • 【高危】Apache Linkis <1.3.2 存在反序列化漏洞(CVE-2023-29216)
  • 初识C语言————3
  • Vue3——一文入门Vue3
  • Python圈的普罗米修斯——一套近乎完善的监控系统
  • 「SQL面试题库」 No_34 连续空余座位