python基础与高级特性(五):函数
python从入门到坚持
一.为什么需要函数
如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数。
二.函数的创建和调用
1.函数的定义与调用
(1)定义一个函数
def test(a, b): "用来完成对2个数求和" print("%d" %(a+b)) test(11, 22) 33
(2)定义一个空函数
定义一个空函数,可以用pass语句:
pass可以用来作为占位符,还没有想好怎么写函数的代码,就可以先方一个pass
def get_passwd(): #定义函数,不执行代码块 pass #pass只是一个占位符,不做任何操作 if _name_ == "_main_": get_passwd()
2.查看test函数文档
help(test)
3.函数返回值
所谓的“返回值”,就是程序中函数完成一件事情后,最后给调用者的结果。
def f2c(fahrenheit): """ 将华氏温度转换为摄氏温度 """ #计算摄氏度 celsius = (fahrenheit - 32)/1.8 return fahrenheit, celsius if _name_ == "_main_": fahrenheit, celsius = f2c(30) print('%.1f华氏度转为摄氏度为%.1f' %(fahrenheit, celsius))
4.定义函数的格式
def 函数名(参数1,参数2,’…'参数n):
函数体
(1)函数名的命名规则要符合python中的命名要求。一般用小写字母和单下划线、数字等组合;匈牙利命名法(sUserName),驼峰式大小写(userName),帕斯卡命名法(UserName)
(2)def是定义函数的关键词,这个简写来自英文单词define
(3)函数名后面是圆括号,括号里面,可以有参数列表,也可以没有参数
(4)千万不要忘记了括号后面的冒号
(5)函数体(语句块),相对与def缩进,按照python习惯,缩进四个空格
5. 函数的优势
从理论上说,不用函数,也能够编程,我们在前面已经写了程序,就没有写函数,当然,用python的内建函数姑且算了。现在之所以使用函数,主要是:
(1)降低编程的难度(分而治之的思想)
(2)代码重用。避免了重复劳动,提高了工作效率。
三.变量作用域
1.局部变量
局部变量:就是在函数内部定义的变量。
不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响;
局部变量的作用:为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用。
2.全局变量
全局变量:如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量。
(1)在函数外边定义的变量叫做全局变量
(2)全局变量能够在所有的函数中进行访问
(3)如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
(4)如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
小技巧:强龙不压地头蛇(就近原则)
不使用global声明全局变量时不能修改全局变量?
global的本质是声明可以修改全局变量的指向, 即变量可以指向新的数据。
1). 不可变类型的全局变量: 指向的数据不能修改, 不使用global时无法修改全局变量。
2). 可变类型的全局变量: 指向的数据可以修改, 不使用global时可以修改全局变量。
四.参数传递
1.形参与实参
形参:定义时小括号中的参数,用来接收参数用的,称为“形参”
实参:调用时小括号中的参数,用来传递给函数用的,成为“实参”
2.参数检查
调用函数时,如果参数个数不对,python解释器会自动检查出来,并抛出TypeError;如果参数类型不对,python解释器就无法帮我们检查。数据类型检查可以用内置函数isinstance实现。
3.默认参数
调用函数时,如果没有指定某个参数将抛出异常,即在定义函数时,直接指出形式参数的默认值。这样,当没有传入参数时,则直接使用定义函数时设置的默认值。定义带有默认值参数的函数语法格式如下:
def functionname(…, [parameter1 = defaultvalue1])
[functionbody]
参数说明:
functionname:函数名称,在调用函数时使用。
parameter1 = defaultvalue1:可选参数,用于指定向函数中传递的参数,并且为该参数设置默认值为defaultvalue1。
functionbody:可选参数,用于指定函数体,即该函数被调用后,要执行的功能代码。
默认参数注意事项:
(1)有多个参数时,变化大的放前面,变化小的放后面;
(2)必选参数在前,默认参数在后。
def mypow(x: int, y: int = 2) -> int: """ 求x的y次方 :param x: :param y: :return: """ return x ** y # # mypow(3, 2) # mypow(4, 2) # 如果传递一个参数, x=3, y没有传递就是默认值2; print(mypow(3)) # 如果传递2个参数, x=3, y有默认值2, 但是3会覆盖默认值,也就是求2的三次方; print(mypow(2, 3))
4.可变参数
可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个。
如果已经有一个list或者tuple,要调用一个可变参数怎么办?
(1)python允许你在list或tuple前面加一个*号;
(2)把list或tuple的元素变成可变参数传进去;
# *nums用来接收多个变量/参数, 接收近来的nums是一个元组; def numSquare(*nums): """ 求n个数的平方 :param nums: :return: """ # print(nums) result = 0 for num in nums: result += pow(num, 2) print(result) numSquare() numSquare(1) numSquare(1, 2, 3) numSquare(3, 4, 5, 6, 7) # # *score可以存多个数值; # low, *score, high = [1, 2, 3, 4, 5, 6100] ###
5.关键字参数
关键字参数允许传入0个或任意个含参数名的参数;这些关键字参数在函数内部自动组装为一个底层它;关键字参数用**kwargs;
# **kwargs: 关键字参数, 接收的kwargs是一个字典; def recordStudentInfo(name, sid, **kwargs): """ 录入学生信息, 必填的内容姓名和学号, 其他的可以自己输入 :param name: :param sid: :return: """ print(""" 姓名: %s 学号: %s """%(name, sid)) for key, value in kwargs.items(): print("\t %s: \t%s" %(key, value)) recordStudentInfo("西部开源", '001', score=100, courses=['python', 'c', 'Linux'])
6.参数组合
参数组合是指可以必选参数,默认参数,可变参数和关键字参数一起使用。参数定义的顺序必须是:必选参数,默认参数,可变参数和关键字参数。
7.参数总结
**对于任意函数,都可以通过类似func(*args,kw)的形式调用它。
五.匿名函数
匿名函数:指一类无须定义标示符的函数或子程序。python用lambda语法定义匿名函数,只需要用表达式而无需申明。(省略了用def声明函数的标准步骤)
lambda函数的语法只包含一个语句,如下:
lambda[arg1 [,arg2, …argn]] : expression
lambda函数能接收任何数量的参数,但只能返回一个表达式的值。
lambda_sum = lambda arg1, arg2 : arg1+arg2 print("运行结果: ", lambda_sum(1, 2)) print("运行结果: ", lambda_sum(3, 5))
六.递归函数
递归函数:一个函数在内部调用自己本身,这个函数就是递归函数。
递归函数原理:
1.常用的递归函数
(1)求阶乘
def recursive_factorial(num): """ 使用递归求num的阶乘 """ # 如果num等于0或者1, 返回1; if num in (0, 1): return 1 # num的阶乘为num*(num-1)! else: return num * recursive_factorial(num - 1) print("3的阶乘: ", factorial(3)) print("6的阶乘: ", factorial(6)) print("3的阶乘: ", recursive_factorial(3)) print("6的阶乘: ", recursive_factorial(6)) print("998的阶乘: ", recursive_factorial(998))
(2)斐波那契数列
""" 斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列: 1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义: F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*) """ def fib(num): """ 斐波那契数列 :param num: :return: """ if num <= 2: return 1 else: return fib(num - 1) + fib(num - 2) result = fib(4) print(result)
(3)汉诺塔问题
moveCount = 0 def hanoi(n, a='A', b='B', c='C'): """ :param n:盘子个数 :param a:初始塔 :param b:缓存塔 :param c:目标塔 :return:移动次数 """ if n == 1: global moveCount moveCount += 1 print(a, "--->", c) else: # 只是调用自己, 并没有真实的移动; # 1). 打开冰箱门 hanoi(n - 1, a, c, b) # 2). 把大象放进去 hanoi(1, a, b, c) # 3). 把冰箱门close hanoi(n - 1, b, a, c) hanoi(3) print("移动次数:", moveCount)
- python基础3之函数高级特性
- 温故知新python3--基础知识3(函数高级特性)
- 廖雪峰Python的研读笔记(一) Python基础、函数、高级特性
- Python学习1——基础、函数、高级特性
- python学习(3)——字典,函数及其高级特性
- Python基础之三高级特性
- python:函数的高级特性
- Python学习笔记3---PYTHON函数与高级特性
- Pythonday5高级特性和高级函数
- python基础知识(二)python高级特性
- python基础-对象高级特性
- python中函数的高级特性以及生成器
- Python高级特性:函数参数传递研究
- python基础与高级特性(八):模块与包
- Python函数的高级特性
- python的高级特性3:神奇的__call__与返回函数
- Python3 基础:高级特性-切片和迭代
- Python高级特性与几种函数的讲解
- python函数高级特性
- python基础与高级特性(七、八):(练习)