Python入门03——函数相关
一、定义函数
定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号 : 起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return相当于返回 None。
一个简单的函数:
def hello():print("Hello World!")
hello()
## 结果为Hello World!
一个简单的传参函数:
# 比较两个数,选择一个最大的
def max(a, b):if a > b:return aelse:return ba = 4
b = 5
print(max(a, b))
## 结果为5
【补充】函数式编程和面向过程编程的区别:
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面向对象:对函数进行分类和封装,让开发“更快更好更强…”
二、函数参数
1. 普通参数
1.形参变量只有在被调用时才分配内存单元,在调用结束后,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此,应预先使用赋值、输入等办法使用参数获得确定值。
3.实参与形参位置一一对应。
2. 默认参数
def func(name, age=18):print("%s:%s" % (name, age))# 指定参数
func('wupeiqi', 19)
# 使用默认参数
func('alex')
## 结果为wupeiqi:19
## alex:18def func(*args):print(args)# 执行方式一
func(11, 33, 4, 4454, 5)
# 执行方式二
li = [11, 2, 2, 3, 3, 4, 54]
func(*li) # 遍历列表中的元素
## 结果为(11, 33, 4, 4454, 5)
## (11, 2, 2, 3, 3, 4, 54)
3. 动态参数:
# 参数组:**字典 *列表
def test(x, *args):print(x)print(args)test(1, ['z', 'y', 'z']) # 将列表当成一个整体传给args
## 结果为1
## (['z', 'y', 'z'],)
test(1, *['z', 'y', 'z']) # 加*可以遍历取到其值
## 结果为1
## ('z', 'y', 'z')
一个简单的例子:
def test(* params):print('参数的长度是:', len(params))print('第二个参数是:', params[1])test(1, 'zhai', 2000, [2, 5, 0]) # 打包成元组传给* params
## 结果为 参数的长度是: 4
## 第二个参数是: zhai
位置参数和关键字:
def test(x, *args, **kwargs):print(x)print(args)print(kwargs)test(1, 2, 3, 1, 1, y=2, z=6) # 位置参数和关键字
## 结果为1 位置参数一一对应
## (2, 3, 1, 1)
## {'y': 2, 'z': 6} 关键字传值
三、函数返回值
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,以下实例演示了 return 语句的用法:
# 定义求和函数
def sum(arg1, arg2):# 返回2个参数的和."total = arg1 + arg2print("函数内 : ", total)return total# 调用sum函数
total = sum(10, 20)
print("函数外 : ", total)
四、局部变量与全局变量
局部变量的作用域在函数内。
count = 0 # 定义全局变量countdef MyCount():count = 100000 # 函数内部定义的变量作用域在函数内print(count)print(count) # 在函数外值仍未改变 #结果为0
MyCount() ## 100000
若想在函数内部使用全局变量,必须在前面加上global。
count = 0 # 定义全局变量countdef MyCount():global count # 使用全局变量countprint(count)print(count) ## 结果为0
MyCount() ## 0
五、嵌套函数和闭包
1. 嵌套函数
python支持在函数内定义另一个函数。
def func1():print("func1 is running!")def func2():print("func2 is running!")func2()func1() # 调用func1方法
## 结果为func1 is running!
## func2 is running!
如果直接调用func2方法会出现如下所示的情况,编译器无法找到对应的func2方法,于是它认为该方法没有被定义。
2. 闭包
简单来说就是一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行。这样的一个函数我们称之为闭包。
一个简单的例子:
def fun_x(x):def fun_y(y):return x * yreturn fun_y # 此处不加括号是为了返回函数值# 第一种赋值方式
res = fun_x(2)
print(type(res)) # 这里的res是一个函数类型,所以我们还需要对它进行调用
print(res(5))# 第二种赋值方式
print(fun_x(2)(5))
运行结果为:
在嵌套函数的情况下,内部函数引用外部函数的局部变量。该例中,fun_y函数中引用了fun_x的局部变量x,所以fun_y函数就是闭包。fun_y是内部函数,fun_x是内部函数的外部作用域但不是全局作用域。
为了加深理解,引入了下一个例子:
def Fun1():x = 5def Fun2():x *= xreturn xreturn Fun2()Fun1()
上述的代码运行时会报错:UnboundLocalError: local variable ‘x’ referenced before assignment。赋值前引用了局部变量“x”,解释器不明白x是全局变量还是局部变量,也可能是局部变量同全局变量同名了。
【解决方案1】将变量改为列表类型。
因为函数变量的存储是放在栈里面的,而列表是不存在栈中的,所以列表元素可以被内置函数所引用。
def Fun1():x = [5]def Fun2():x[0] *= x[0]return x[0]return Fun2()print(Fun1())
## 结果为25
【解决方案2】使用nonlocal关键字。
nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。
nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。
def Fun1():x = 5def Fun2():nonlocal x # 只能用于嵌套函数中,并且外层函数中定义了相应的局部变量x *= xreturn xreturn Fun2()print(Fun1())
## 结果为25
六、匿名函数
python 使用 lambda 来创建匿名函数。所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
函数只有一个参数的情况:
####################### 普通函数 ######################
# 定义函数(普通方式)
def ds(x):return 2 * x + 1print(ds(5))
## 结果为11# 用lambda简化函数
g = lambda x : 2 * x + 1
print(g) # lambda返回的是函数类型
print(g(5))
## 结果为<function <lambda> at 0x000001C21921A280>
## 11
函数中有两个参数的情况:
def add(x, y):return x + yprint(add(5, 7))g = lambda x, y : x + y
print(g(5, 7))
## 结果为12
lambda表达式的作用:
- python写一些执行脚本时,使用lambda就可以省下定义函数过程,比如说我们只是需要写个简单的脚本来管理服务器时间,就不需要专门定义一个函数然后再写调用,使用lambda就可以使得代码更加精简。
- 简化代码的可读性,省去def步骤。
- 对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起个名字也是比较头疼的问题,使用lambda就不需要考虑命名的东西。
七、递归
【例1】利用函数编写斐波那契数列(如下图所示)。
# 递归实现算出第n次的结果
def fibonacci(n):if n == 0:return 0elif n == 1:return 1else:return fibonacci(n - 2) + fibonacci(n - 1)res = fibonacci(5)
print(res)
【例2】分别用递归方式和非递归方式实现求一个数的阶乘。
递归方法:
def factorial_recur(x):if x == 1: # 记得写递归出口return 1else:return x * factorial_recur(x - 1)number = input("请输入一个正整数用来求其阶乘:")
res = factorial_recur(int(number))
print("%s的阶乘为%s" % (number, res))
## 输入5结果为120
非递归方法:
def factorial(x):res = 1for i in range(1, x+1):res = i * resprint(res)n = input("请输入一个正整数用来求其阶乘:")
factorial(int(n))
## 输入5结果为120
【例3】递归实现汉诺塔。
def Hanoi(n, a, b, c): # n代表盘子数,借助B从A移动到Cif n == 1: # 递归出口print(a, '-->', c)else:Hanoi(n - 1, a, c, b) # 将前n-1个借助C从A移动到Bprint(a, '-->', c) # 将最底下的一个盘子从A移动到C上Hanoi(n - 1, b, a, c) # 将暂时存放在B上的前n-1个借助A放到C上num = int(input("请输入汉诺塔的层数:"))Hanoi(num, 'A', 'B', 'C') # 注意字符串实需加''符号
运行结果为:
八、内置函数
注:查看详细,点击官方说明文档
1. open( )函数
open函数用于文件处理。
操作文件时,一般需要经历如下步骤:①打开文件;② 操作文件
open打开文件
文件句柄 = open('文件路径', '模式')
打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。
打开文件的模式有:
- r ,只读模式【默认】
- w,只写模式【不可读;不存在则创建;存在则清空内容】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【可读;不存在则创建;存在则只追加内容】
"+" 表示可以同时读写某个文件:
- r+, 读写【可读,可写】
- w+,写读【可读,可写】
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】
"b"表示以字节的方式操作:
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型。
下图很好的总结了这几种模式:
class file(object)def close(self): # real signature unknown; restored from __doc__关闭文件def fileno(self): # real signature unknown; restored from __doc__文件描述符 return 0 def flush(self): # real signature unknown; restored from __doc__刷新文件内部缓冲区passdef isatty(self): # real signature unknown; restored from __doc__return Falsedef next(self): # real signature unknown; restored from __doc__获取下一行数据,不存在,则报错passdef read(self, size=None): # real signature unknown; restored from __doc__读取指定字节数据passdef readinto(self): # real signature unknown; restored from __doc__读取到缓冲区,不要用,将被遗弃passdef readline(self, size=None): # real signature unknown; restored from __doc__仅读取一行数据passdef readlines(self, size=None): # real signature unknown; restored from __doc__读取所有数据,并根据换行保存值列表return []def seek(self, offset, whence=None): # real signature unknown; restored from __doc__指定文件中指针位置passdef tell(self): # real signature unknown; restored from __doc__获取当前指针位置passdef truncate(self, size=None): # real signature unknown; restored from __doc__截断数据,仅保留指定之前数据passdef write(self, p_str): # real signature unknown; restored from __doc__写内容passdef writelines(self, sequence_of_strings): # real signature unknown; restored from __doc__将一个字符串列表写入文件passdef xreadlines(self): # real signature unknown; restored from __doc__可用于逐行读取文件,非全部pass
2. filter( )函数
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将下划线返回 True 的元素放到新列表中。
语法格式为:
filter(function, iterable)
# function -- 判断函数
# iterable -- 可迭代对象
# 返回值为一个迭代器对象
一个简单的例子:
v1 = filter(None, [1, 0, False, True])
print(v1) # 返回了一个过滤器对象
v2 = list(filter(None, [1, 0, False, True])) # 转换成list类型
print(v2) # 过滤掉为0和False的值def odd(x):return x % 2 # 如果是偶数的话,返回的就是0;有返回值1的都是奇数v3 = print(odd(10)) # 10是偶数,所以返回0v4 = list(filter(lambda x : x % 2, range(10)))
print(v4)
运行结果为:
3. map( )函数
map() 函数会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
一个简单的例子:
def square(x): # 计算平方数return x ** 2
v1 = list(map(square, [1, 2, 3, 4, 5])) # 计算列表各个元素的平方
print(v1)
## 结果为[1, 4, 9, 16, 25]v2 = list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))
print(v2) # 输出的结果是把range(10)中每个对象放入前面的函数中做处理,再输出
## 结果为[1, 4, 9, 16, 25]
Python入门03——函数相关相关推荐
- 哪本python入门书内容最详细-重磅 | 由浅入深的 AI 学习路线,最详细的资源整理!...
原标题:重磅 | 由浅入深的 AI 学习路线,最详细的资源整理! [导读] 本文由知名开源平台,AI技术平台以及领域专家: Datawhale, ApacheCN, AI有道和 黄海广博士联合整理贡献 ...
- python课程推荐-课程推荐:四天人工智能 python入门体验课
作为一名被大数据和数量信息包裹的文案,我们必定要在文案力.创意和策略能力之外,准备一个加薪引擎--以技术思维处理数据运算的能力. 只有跑得足够快,才能不被行业当成 "老古董" 落下 ...
- python入门基础代码图-Python入门基础学习一
------------恢复内容开始------------ Python简介 Python由来 Python的创始人为吉多·范罗苏姆.1989年的圣诞节期间,吉多范罗苏姆为了再阿姆斯特丹大法时间,决 ...
- python快速编程入门课后程序题答案-Python 入门编程题:1~10(答案)
Python 入门编程题:1~10(答案) 提示:最好还是先思考,先编写,再看答案哦 ^_^ 1. for i in range(1, 5): for j in range(1,5): for k i ...
- python入门导引
实习需要,读了python的程序,归来决定系统地学习一下这个被称为"学得最划算"的语言. 集各家之言,先对Python做一个简介: python是一种面向对象的解释性的计算机程序设 ...
- python3入门与进阶笔记_16_变量进阶 — 黑马程序员《Python入门教程完整版》笔记...
变量进阶(理解) - 黑马程序员<Python入门教程完整版>笔记 目标变量的引用 可变和不可变类型 局部变量和全局变量 01. 变量的引用变量 和 数据 都是保存在 内存 中的 在 Py ...
- python十分钟教程_简洁的十分钟Python入门教程
[简介] Python是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. [特点] 1 Python使用C语 ...
- Python入门知识点总结
Python基础的重要性不言而喻,是每一个入门Python学习者所必备的知识点,作为Python入门,这部分知识点显得很庞杂,内容分支很多,大部分同学在刚刚学习时一头雾水. 本节将Python的知识点 ...
- python入门if语句练习_python入门视频:09 if语句_练习.mp4
本视频课程目录如下: python6天学习基础课程 ├─01天 │ python入门视频:01 计算机组成-硬件设备.mp4 │ python入门视频:02 计算机组成-软件 ...
最新文章
- 深入浅出Yolov3和Yolov4
- python list排序的两种方法及实例讲解
- 操作多个表_7_基于子串的连接
- NLTK基础 | 一文轻松使用NLTK进行NLP任务(附视频)
- [转]蓝牙基带数据传输机理分析
- mongodb 安装、启动
- org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved
- comsol线圈不能加电流激励_comsol里面如何绘制三维的激励线圈?
- VisualSVNServerTools(在线修改VisualSVN密码)
- linux源码gpio模拟i2c,linux内核gpio模拟i2c实例.doc
- 计算机教师的幸福,如何成为一名幸福信息技术教师
- python装饰器详解-python中的装饰器详解
- String中的intern方法详解
- 分期手续费率转换成年利率
- 更新了pandas后,ix方法不能使用的替代办法
- Redmi首款超高性价比笔记本明日开售 售价3999元起
- 【转】最优传输理论---(微信公总号:老顾谈几何)顾险峰
- matlab syms函数例题,matlab函数计算syms f o s z k D t m q T x;p=f-o-(s-o)*(1-erf(0.5*
- 故障描述:服务器应用程序不可用
- 不思议迷宫:逆向后的放置play
热门文章
- Java网课基础笔记(4)19-07-16
- oracle 查找不重复的数据,oracle不用distinct查找不重复记录和删除重复记录
- Spring框架的基本使用
- 盗梦空间科普札记之一:梦里乾坤嵌套深,醒来可知在哪层?
- “空天地海”一体化的海上应急通信网络技术综述
- 设置centos7.3的YUM源为国内阿里云源
- 微信公众平台从入门到精通二
- 基于javaweb的毕设基于java的系统设计与开发
- [xdm+ip]ubuntu下载数据慢或者不通
- 打印表格打印机没有反应_打印机没反应怎么回事