python之函数

函数简介

        函数是可重用的程序代码块.函数的作用,不仅可以实现代码的复用,更能实现代码的一致性.一致性指的是,只要修改函数的代码,则所有调用该函数的地方都能得到体现
        在编写 函数 时, 函数体 中的代码只是对代码实现了封装,并增加了 函数调用 传递参数 返回计算结果 等内容

函数的基本概念

1. 一个程序由一个个任务组成;函数就是代表一个任务或者一个功能
2. 函数代码复用的通用机制

Python 函数的分类

1. 内置函数
我们前面使用的 str()、list()、len() 等这些都是 内置函数 ,我们可以拿来直接使用
2. 标准库函数
我们可以通过 import语句导入库 ,然后使用其中定义的函数
3. 第三方库函数
Python社区也提供了很多高质量的库.下载安装这些库后,也是通过import语句导
入,然后可以使用这些 第三方库的函数
4. 用户自定义函数
用户 自己定义的函数 ,显然也是开发中适应用户自身需求定义的函数.今天我们学习的
就是如何自定义函数

函数的定义和调用

Python中,定义函数的语法如下:
         def 函数名 ([参数列表]) :
                '''文档字符串'''
                函数体/若干语句
要点:
1. 我们使用def来定义函数,然后就是一个空格和函数名称;
        Python执行 def 时,会创建一个 函数对象 ,并绑定到 函数名变量上
2. 参数列表
        (1) 圆括号 内是 形式参数列表 ,有多个参数则 使用逗号隔开
        (2) 形式参数 不需要声明类型,也 不需要指定函数返回值类型
        (3) 无参数,也必 须保留空的圆括号
        (4) 实参列表 必须与形参列表一一对应
3. return返回值
        (1) 如果 函数体 包含return语句 ,则 结束函数执行并返回值
        (2) 如果 函数体 不包含return语句 ,则返 回None值
4. 调用函数之前,必须要先定义函数,即先调用def创建函数对象
        (1) 内置函数 对象会自动创建
        (2) 标准库 第三方库函数 ,通过 import 导入模块时,会执行模块中的 def语句

形参和实参

        上面的 printMax函数 中,在定义时 写的printMax(a,b)  a和b称为“形式参数”,简称“形参” .也就是说, 形式参数 是在定义函数时使用的.  形式参数 的命名只要符合“标识符”命名规则即可
        在调用函数时, 传递的参数称为“实际参数”,简称“实参” .上面代码中, printMax(10,20),10和20就是实际参数

文档字符串(函数的注释)

程序的可读性最重要,一般建议在函数体开始的部分附上函数定义说明,这就是“文档字符 串”,也有人成为“函数的注释”.我们通过三个单引号或者三个双引号来实现,中间可以加入多行文字进行说明

返回值

return返回值要点:
        1. 如果 函数体 包含return语句 ,则 结束函数执行并返回值
        2. 如果 函数体 不包含return语句 ,则 返回None值
        3. 要 返回多个返回值 ,使用 列表、元组、字典、集合 将多个值“存起来”即可

函数也是对象,内存底层分析

Python中,“一切都是对象”.实际上,执行def定义函数后,系统就创建了相应的函数
对象.我们执行如下程序,然后进行解释:
上面代码 执行def 时,系统中会创建 函数对象, 并通过 print_star 这个变量进行引用
我们执行“c=print_star”后,显然将print_star变量的值赋给了变量 c,内存图变成了:
显然,我们可以看出变量cprint_star都是指向了同一个函数对象.因此,执行c(3)和执行print_star(3)的效果是完全一致的.Python中,圆括号意味着调用函数.在没有圆括号的情况下,Python会把函数当做普通对象

变量的作用域(全局变量和局部变量)

变量起作用的范围称为变量的作用域,不同作用域内同名变量之间互不影响.变量分为:
局变量、局部变量
全局变量:
        1. 在 函数 定义之外 声明的变量 . 作用域 为定义的模块,从定义位置开始直到模块
结束
        2. 全局变量 降低了函数的 通用性 可读性 .应 尽量避免全局变量的使用
        3. 全局变量 一般 做常量使用
        4. 函数内要 改变全局变量的值 ,使用 global 声明一下
局部变量:
        1. 在 函数体 中(包含形式参数) 声明的变量
        2. 局部变量 的引用 比全局变量快 ,优先考虑使用
        3. 如果 局部变量和全局变量同名 ,则在函数内 隐藏全局变量 ,只 使用同名的局部变量

局部变量和全局变量效率测试

局部变量查询访问速度全局变量,优先考虑使用,尤其是在循环的时候.在特别强调效率的地方或者循环次数较多的地方,可以通过将全局变量转为局部变量提高运行速度

参数的传递

函数的参数传递本质上就是:从实参到形参的赋值操作.Python中“一切皆对象”,所有的赋值操作都是“引用的赋值”.所以,Python中参数的传递都是“引用传递”,不是“值传递”.具体操作时分为两类:
        1. 对“ 可变对象 ”进行“ 写操作 ”,直接 作用于原对象本身
        2. 对“ 不可变对象 ”进行“ 写操作 ”,会 产生一个新的“对象空间”, 并用 新的值
充这块空间.(起到其他语言的“ 值传递 ”效果,但 不是“值传递” )
可变对象有:
         字典、列表、集合、自定义的对象
不可变对象有:
         数字、字符串、元组、function
传递可变对象的引用
         传递参数 可变对象 (例如:列表、字典、自定义的其他可变对象等),实际传递的还是对
象的引用.在函数体中 不创建新的对象拷贝 ,而是可以 直接修改所传递的对象

传递不可变对象的引用

         传递参数 不可变对象 (例如:int、float、字符串、元组、布尔值),实际传递的还是对
象的引用.在” 赋值操作 ”时,由于 不可变对象无法修改 ,系统 会新创建一个对象
显然,通过id值我们可以看到n和a一开始是同一个对象.给n赋值后,n是新的对象

浅拷贝和深拷贝

浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用         copy(浅拷贝)
深拷贝:会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象    deepcopy(深拷贝)

 传递不可变对象包含的子对象是可变的情况

参数的几种类型

位置参数

函数调用 时, 实参默认按位置顺序传递 ,需要 个数和形参匹配 .按位置传递的参数,称为:
位置参数

默认值参数

我们可以为某些 参数设置默认值, 这样这些参数在传递时就是可选的.称为“ 默认值参数 ”.
默认值参数 位置参数后面

命名参数

我们也可以 按照形参的名称传递参数, 称为“ 命名参数 ”,也称“ 关键字参数

可变参数

可变参数 指的是“ 可变数量的参数 ”.分两种情况:
        1. *param(一个星号) ,将多个参数收集到一个“ 元组 ”对象中
        2. **param(两个星号) ,将多个参数收集到一个“ 字典 ”对象中

强制命名参数

带星号 的“ 可变参数 ”后面 增加新的参数 ,必须在调用的时候“ 强制命名参数

lambda表达式和匿名函数

         ambda表达式 可以用来 声明匿名函数  lambda函数 是一种简单的、在同一行中定义函数
的方法 lambda函数 实际生 成了一个函数对象
         lambda表达式 只允许包含一个表达式 , 不能包含复杂语句 ,该表达式的计算结果就是 函数
的返回值
lambda表达式的基本语法如下:
                lambda arg1,arg2,arg3... : <表达式>
arg1/arg2/arg3为 函数的参数    <表达式>相当于函数体  运算结果是: 表达式的运算结果

eval()函数

功能 :将 字符串str 当成有效的表达式来 求值并返回计算结果
语法 : eval(source[, globals[, locals]]) -> value
参数
         source :一个 Python表达式 函数compile() 返回的代码对象
         globals :可选 必须是dictionary
         locals :可选 任意映射对象

递归函数
递归函数指的是 :自己调用自己的函数,在函数体内部直接或间接的自己调用自己
递归函数必须包含两个部分:
1. 终止条件
        表示递归什么时候结束,一般用于 返回值 ,不再调用自己
2. 递归步骤
        把第n步的值和第n-1步相关联
小测试

 

 

 

 嵌套函数(内部函数)

嵌套函数 : 在函数内部定义的函数!

 

 

 一般在什么情况下使用嵌套函数?

1. 封装 - 数据隐藏
        外部无法访问“嵌套函数”。
2. 贯彻 DRY(Don’t Repeat Yourself) 原则
        嵌套函数,可以让我们在函数内部避免重复代码
3. 闭包
nonlocal 关键字
nonlocal
        用来声明外层的局部变量
global
        用来声明全局变量

  

 

LEGB 规则

        如果某个name映射在局部(local)命名空间中没有找到,接下来就会在闭包作用域(enclosed)进行搜索,如果闭包作用域也没有找到,Python就会到全局(global)命名空间中进行查找,最后会在内建(built-in)命名空间搜索(如果一个名称在所有命名空间中都没有找到,就会产生一个NameError)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

93蔺先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值