Python基础——函数(二)
文章目录
- 函数和过程
- 函数变量的作用域
- 局部变量
- 全局变量
- global关键字
- 内嵌函数(内部函数)
- 闭包(closure)
- lambda表达式
- 两个常用BIF:filter()和map()
函数和过程
在许多编程语言中,函数和过程其实是分开的。一般认为函数(function)是有返回值的,而过程(procedure)是简单、特殊并且没有返回值的。Python严格来说,只有函数,没有过程。举个例子:
调用print(hello())之后打印了两行文字,第一行我们当然知道是hello()函数执行的,第二行的None是怎么回事呢?其实,当不写return语句的时候,默认Python会认为函数是return None的。所以说Python所有的函数都有返回值。
函数变量的作用域
也许大家已经听说了局部变量和全局变量,变量的作用域也就是平常所说的变量可见性,一般的编程语言都有局部变量(Local Variable) 和 全局变量(Global Variable) 之分。
# 计算折扣价
def discounts(price, rate):final_price = price * ratereturn final_priceold_price = float(input("请输入原价:"))
rate = float(input("请输入折扣率:"))
new_price = discounts(old_price, rate)
print("打折后的价格是:", new_price)
其执行结果如下:
局部变量
这是一个简单的计算折扣价的代码段,来分析一下代码:在函数discounts()中,两个参数是price和rate,还有一个是final_price,它们都是discounts()函数中的局部变量。为什么称为局部变量呢,不妨修改一下代码:
# 计算折扣价
def discounts(price, rate):final_price = price * ratereturn final_priceold_price = float(input("请输入原价:"))
rate = float(input("请输入折扣率:"))
new_price = discounts(old_price, rate)
print("打折后的价格是:", new_price)# 添加一行试图打印局部变量final_price的值
print("打印局部变量final_price的值:", final_price)
可以看到程序像刚才一样输出之后便报错了,错误原因是:final_price没有被定义过,也就是说,Python找不到final_price这个变量。这是因为final_price只是一个局部变量,它的作用只在它的地盘上——discounts()函数的定义范围内——有效,出了这个范围,就不属于它的地盘了,它将什么都不是。
总结一下:在函数里边定义的参数以及变量,都称为局部变量,出了这个函数,这些变量都是无效的。 事实上的原理是,Python在运行函数的时候,利用栈(Stack)进行存储,当执行完该函数后,函数中的所有数据都会被自动删除,所以在函数外边是无法访问到函数内部的局部变量的。
全局变量
与局部变量相对的是全局变量,程序中的old_price、new_price、rate都是在函数外边定义的,它们都是全局变量,全局变量拥有更大的作用域,例如在函数中可以访问到它们:
# 计算折扣价
def discounts(price, rate):final_price = price * rate# 添加一行试图打印全局变量old_price的值print("打印全局变量old_price的值:", old_price)return final_priceold_price = float(input("请输入原价:"))
rate = float(input("请输入折扣率:"))
new_price = discounts(old_price, rate)
print("打折后的价格是:", new_price)
其执行结果为:
可以看到全部变量的访问范围更广,不过使用全局变量的时候要千万小心,在Python中,你可以在函数中肆无忌惮的访问一个全局变量,但是如果你试图去修改它,就会出现下面这样的结果:
# 计算折扣价
def discounts(price, rate):final_price = price * rateold_price = 50 # 这里试图修改全部变量print("在局部变量中修改后的old_price的值是:", old_price)return final_priceold_price = float(input("请输入原价:"))
rate = float(input("请输入折扣率:"))
new_price = discounts(old_price, rate)
print("全局变量old_price现在的值是:", old_price)
print("打折后的价格是:", new_price)
其执行结果为:
出现这个结果的原因是:如果在函数内部试图修改全局变量,那么Python会创建一个新的局部变量替代(名字跟全局变量相同),但真正的全部变量是没有改变的,所以实现会和大家预期的不同。
总结一下:全局变量在整个代码段中都是可以访问到的,但是不要试图在函数内部去修改全局变量的值,因为那样Python会自动在函数内部新建一个名字相同的局部变量代替。
global关键字
上面提到,全局变量的作用域是整个模块,也就是代码段内所有的函数内部都可以访问到全局变量。但需要注意的是,在函数内部仅仅访问全局变量可以,不要试图去修改它。因为那样的话,Python会使用 屏蔽(Shadowing) 的方式“保护”全局变量:一旦函数内部试图修改全局变量,Python就会在函数内部自动创建一个名字一样的局部变量,这样修改的结果只会修改到局部变量,而不会影响全局变量。举个小例子:
如果你认为有必要在函数中去修改这个全局变量,那么你不妨可以使用global关键字来达到目的。
内嵌函数(内部函数)
Python的函数定义是可以嵌套的,也就是允许在函数内部创建另一个函数,这种函数叫作内嵌函数或者内部函数。下面看一个简单的内嵌函数的例子:
关于内部函数的使用,有一个比较值得注意的地方,就是内部函数整个作用域都在外部函数之内,就像上述例子中的fun2()整个函数的作用域都在fun1()里边。除了在fun1()这个函数体中可以随意调用fun2()这个内部函数外,出了fun1(),就没有任何可以对fun2()进行的调用。
如果在fun1()外调用内部函数fun2(),就会报错:
闭包(closure)
闭包(closure)是函数式编程的一个重要的语法结构,函数式编程是一种编程范式,不同的编程语言实现闭包的方式不同,Python中的闭包从表现形式上定义为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。举个例子:
也可以这样写:
通过上面的例子来理解闭包的概念:如果在一个内部函数里(funY就是这个内部函数)对外部作用域(但不是在全局作用域)的变量进行引用(x就是被引用的变量,x在外部作用域funX函数里面,但不在全局作用域里),则这个内部函数(funY)就是一个闭包。
使用闭包需要注意的是,因为闭包的概念就是由内部函数而来的,所以也不能在外部函数以外的地方对内部函数进行调用:
在闭包中,外部函数的局部变量对应内部函数的局部变量,事实上相当于之前讲的全局变量跟局部变量的对应关系,在内部函数中,只能对外部函数的局部变量进行访问,但不能进行修改。
再看一个例子:
这个报错信息跟之前讲解全局变量的时候基本一样,Python认为在内部函数(funY)的x是局部变量的时候,外部函数(funX)的x就被屏蔽了起来,所以执行 x *= x 的时候,在右边根本就找不到局部变量x的值,因此报错。
而在Python3中,对于这个问题,也有解决办法——nonlocal关键字。
如果希望在内部函数里可以修改外部函数里的局部变量的值,那么就可以使用nonlocal关键字,使用方式和global关键字一样:
lambda表达式
Python允许使用lambda关键字来创建匿名函数。
Python中的lambda表达式语法非常精简,其基本语法是:
参 数 1 , 参 数 2 , . . . : 返 回 值 参数1,参数2,... : 返回值 参数1,参数2,...:返回值
在冒号(:)左边放原函数的参数,可以有多个参数,用逗号(,)隔开即可;冒号右边是返回值。
给一个简单的例子:
其写为lambda表达式来定义这个函数,就会变为这样:
我们发现lambda语句实际上是返回一个函数对象,如果要对它进行使用,只需要进行简单的赋值操作即可:
当然,如果有多个参数直接用逗号隔开即可:
lambda表达式的作用:
1、 Python写一些执行脚本时,使用lambda就可以省下定义函数过程,就不需要专门定义一个函数然后再写调用,使用lambda就可以使得代码更加精简。
2、 对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起名是个比较头疼的问题,使用lambda就不需要考虑命名的问题了。
3、 简化代码的可读性,由于阅读普通函数经常要跳到开头def定义的位置,使用lambda函数可以省去这样的步骤。
两个常用BIF:filter()和map()
接下来介绍两个比较实用的BIF:filter()和map()。
一、filter()
这一个内建函数是一个过滤器。我们每天会接触大量的数据,通过过滤器,就可以保留你所关注的信息,把其他不感兴趣的东西直接丢掉。那么Python中的这个filter()是怎么实现这个功能呢?先来看一下Python给出的函数部分注释:
这里只截取了关于函数用法的部分,大概意思是:filter有两个参数,第一个参数可以是一个函数也可以是None,如果第一个参数是一个函数的话,则将第二个可迭代数据里的每一个元素作为函数的参数进行计算,把返回True的值筛选出来;如果第一个参数为None,则直接将第二个参数中为True的值筛选出来。
举几个简单例子:
1、 第一个参数为None时
2、利用filter(),写一个筛选奇数的过滤器:
在学习了lambda表达式后,可以将上述过程转换为一行:
二、map()
map()这个内置函数也有两个参数,仍然是一个函数和一个可迭代序列,将序列的每一个元素作为函数的参数进行运算加工,直到可迭代序列每个元素都加工完毕,返回所有加工后的元素构成的新序列。
其用法和filter()类似,举个简单的例子:
Python基础——函数(二)相关推荐
- Python基础(二)--数据类型,运算符与流程控制
目录 Python基础(二)--数据类型,运算符与流程控制 1 数据类型 1.1 Python中的数据类型 1.2 整数类型(int) 1.3 布尔类型 1.4 浮点类型 1.5 复数类型 1.6 类 ...
- Python基础(二)完结
今天分享又来了呀.ღ( ´・ᴗ・` ) 一起学习进步ღゝ◡╹)ノ♡ 关注公众号,回复"资料全集",不定期最新大数据业内资讯. ❤:在这里跟我一起学习技术.职场.人生.原理.健身.摄 ...
- python 基础复习二
这里写自定义目录标题 python 基础复习二 1.数据类型 2.数据的应用 3.数据的转换 总结 python 基础复习二 1.数据类型 最常用的数据类型有三种--字符串(str).整数(int)和 ...
- 廖雪峰Python基础练习(二)
#廖雪峰Python基础练习(二)# 请利用Python内置的hex()函数把一个整数转换成十六进制表示的字符串: 答: # -*- coding: utf-8 -*-n1 = 255 n2 = 10 ...
- Python基础-函数,高阶函数
Python基础-函数 1.函数的定义和函数的执行流程: """ 函数学习 """print('程序开始') a = 10 # 在内存中申请 ...
- 数据挖掘之Python基础(二)函数与文件读写
前言 前一篇文章我们讲到了Python的基本的数据结构,如果对于Python不是很熟悉,建议先看前一篇文章,或者关注公众号QStack,里面有全部文章. if条件语句 基本所有语言的if条件语句都差不 ...
- 第三章:Python基础の函数和文件操作实战
本課主題 Set 集合和操作实战 函数介紹和操作实战 参数的深入介绍和操作实战 format 函数操作实战 lambda 表达式介绍 文件操作函数介紹和操作实战 本周作业 Set 集合和操作实战 Se ...
- python基础函数大全pdf,python函数大全及使用
Python的函数都有哪些? Python 函数函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数, ...
- python请输入姓名性别以及年龄jack男20_【详细】Python基础(二)
文章目录 前言 7. 公共操作 7.1 运算符 7.2 公共方法 7.3 容器类型转换 8. 推导式 8.1 列表推导式 8.2 字典推导式 8.3 集合推导式 8.4 推导式总结 9. Python ...
最新文章
- Linux的Unicon资料
- 学习人必看!空军老兵自学编程,仅隔一年成为国土安全部的数据库分析师
- excel公式 某一个单元格等于另一个单元格的值_EXCEL函数学习5——COUNTIF函数
- sublime text 2中Emmet8个常用的技巧
- spark减少内存消耗_将内存消耗减少20倍
- python画折线图代码实现_python如何绘制分布折线图 python绘制分布折线图代码示例...
- codis配置_Codis的安装配置
- mave构建docker镜像Dokerfile,上传华为云镜像服务器CCE
- 设计模式-第一篇之单例模式
- anaconda简单解决PackagesNotFoundError: The following packages are not available from current channels:
- UDS常用诊断服务介绍
- stm32电容触摸按键的实现
- 手动实现获取微信openid
- Last chance to join 500+ others in Australia
- 视频水印怎么去掉?有什么好的去水印工具吗?
- tf.layers.flatten()使用
- wxpy 微信聊天机器人的实现
- 小马智行联合创始人兼CTO楼天城:无人驾驶:一场科技主导的“登月之旅”
- python 视频教程大全下载地址
- 应对口译口试之三大策略