什么是函数
所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用 。函数的使用包含两个步骤 :
1.定义函数–封装独立的功能
2.调用函数–享受封装的成果
使用函数的背景
1.在开发时,使用函数可以提高编写的效率以及代码的重用
2.函数是带名字的代码块,用于完成具体的工作
3.需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用该任务的函数,让python运行其中的代码,你将发现,通过使用函数,程序编写,阅读,测试和修复都将更容易
函数的范例
def test(a , b):
print(" %d "%(a + b))
test(11 , 23)
空函数
定义一个什么都不做的空函数,可以用pass语句:
pass可以用来作为占位符,还没想好怎么写的函数代码,就可以先放一个pass,让代码运行起来。
def get_passwd( ):
pass
if __name__ == "__main__":
get _pass( )
函数返回值
所谓返回值,就是程序中函数完成一个事情后,诸侯给调用者的结果。没有返回值,默认返回None。
定义函数的格式
def 函数名(参数1,参数2,。。。):
函数体(语句块)
(1)函数名的命名规格要符合python中的命名要求。一般要用小写之母和单下划线、数字组合。
(2)def 是定义函数的关键字,来自define。
(3)函数名后面的圆括号,括号里面可以有参数亦可以没参数。
(4)括号后面有冒号。
(5)函数体,相对于def 缩进,按照python 习惯缩进4格。
def printOneLine():
print("-"*30)
def printNumLine(num):
i = 0
while i < num:
printOneLine()
i + = 1
if __name__ == "__main__":
printNumLine(3)
运行结果:
例:猜数字游戏(函数版)
随机生成1-100内的一个数字,输入猜的次数,然后输入一个数,如果不一样就会提醒太大或太小,在次数用完前匹配例就成功,否则失败。
import random
#1). 形参-定义函数时里面的参数: 形式参数(可以任意修改名字)
#2). 如果函数没有return, 默认会返回None;
# 3). 实参-调用函数时指定的值 : 实际存在的参数
def isEuqal(guessNum, gameNum):
"""
判断用户猜测的数字和游戏给定的数字是否相等?
:param guessNum:
:param gameNum:
:return: Bool-是/否
"""
if guessNum > gameNum:
print("太大了")
return False
elif guessNum < gameNum:
print("太小了")
return False
else:
print("恭喜你, 中了100万")
return True
def main():
"""
脚本的主函数
:return:
"""
gameNum = random.randint(1, 100)
num = int(input('请输入猜数字最多次数:'))
for count in range(num):
guessNum = int(input("请开始游戏, 猜测数字(1-100):"))
if isEuqal(guessNum, gameNum):
break
else:
print("游戏结束, 一百万还很遥远")
main()
运行结果:
函数的优势
从理论上来说,不用函数,也可以编程。现在使用函数主要是:
(1)降低编程难度(分而治之)
(2)代码重用。避免重复,提高效率。
局部变量
就是在函数内部定义的变量。
不同的函数,可以定义相同名字的局部变量,各不影响。
局部变量的作用为了临时保存数据需要在函数中定义变量来进行存储,中就是他的作用。
全局变量
如果一个变量,既能在一个函数中使用,也可以在其他函数中使用,这样的变量就是全局变量。
在函数外面定义的变量是全局变量
全局变量能够在所有函数中进行访问。
如果在函数中修改全局变量,那么久需要使用global 进行声明,否则出错。
如果全局变量的名字和局部变量的名字相同。那么使用的是局部变量的(强龙不压地头蛇,即就近原则 )
怎么不使用global 声明全局变量时怎么修改全局变量:
global 的本质是声明可以修改全局变量的指向,即变量可以指向新的数据。
(1)不可变数据类型的全局变量:指向的数据类型不能修改,不适用global时无法修改全局变量。
(2)可变数据类型的全局变量:指向的数据可以修改,不使用global 时可以修改全局变量。
# 定义全局变量
allMoney = 100
operator = []
def save_money(money):
"""存钱"""
global allMoney
print("存钱前:", allMoney, operator)
allMoney += money
# 为什么operator不需要声明为全局变量?因为它是可变类型的全局变量,不需要global声明
operator.append('存钱操作')
print("存钱后:", allMoney, operator)
def view_money():
"""查询金额"""
#allMoney = 500
operator.append("查询金额操作")
print("查询金额:", allMoney, operator)
if __name__ == '__main__':
save_money(50)
view_money()
运行效果:
4. 参数的传递
形参
定义时,小括号中的参数,用来接收参数用的。
实参
调用时小括号中的参数,用来传递给函数用的。
参数检查
调用函数时,如果参数个数不对,python 解释器会检查出来,并抛出TypeError;
但是:
如果参数类型不对,python 解释器就无能为力了。
数据类型检出可以用内置函数isinstance 实现。
告诉解释器, 形参的类型, 和返回值的类型
def add(x: int, y: int) -> int:
# if type(x) == int and type(y) == int:
# iterable可迭代的,
# all是python的内置方法, 如果全为True, 返回True, 有一个为Flase,返回False;
# any是python的内置方法, 如果全为False, 返回False, 有一个为True,返回True;
if all([isinstance(x, int), isinstance(y, int)]):
return x + y
print(add(1, 2))
如果参数类型不对,Python 解释器就无法帮我们检查。(type,isinstance )
print(add('hello', 1))
调用函数时,如果参数个数不对,Python 解释器会自动检查出来,并抛出 TypeError;
print(add('hello'))
isinstance查看/判别数据类型的
print(isinstance('hello', str))
print(isinstance('hello', int))
默认参数
需求:定义一个函数,计算X值得N次方,那如果计算X平方是,只需要传入X值时怎么办?
默认参数可以降低调用函数的难度。
默认参数注意事项:
有多个参数时,变化大的放前面,变化小的放后面。
必选参数在前,默认参数在后。
def mypow(x: int, y: int = 2) -> int:
"""
求x的y次方 """
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))
运行结果:
可变参数:
可变参数就是可以传入参数的个数是可变的,可以是0, 1,2,。。。* args
以数学题为例,给定一组a, b, c…
请计算a2 + b2 +c2 +…
如果已经有一个list 或者tuple ,要调用一个可变参数怎么办?
(1)python 允许在list 或者tuple 前面加一个 (※号)
(2)把list 或者tuple 的元素变成可变参数传进去。
largs = [1,2,3]
func(largs[0],largs[1],largs[2])
func(*largs)
#*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)
允许结果:
关键字参数
关键之参数允许传入0个或者人一个参数名的参数
这些关键字参数在函数内部自动组装成一个dict。
关键字参数用**kwargs。
# **kwargs: 关键字参数, 接收的kwargs是一个字典;
def recordStudentInfo(name, sid, **kwargs):
"""
录入学生信息, 必填的内容姓名和学号, 其他的可以自己输入
"""
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'])
运行结果:
组合参数
组合参数指必选参数、默认参数、可变参数、关键字参数一起使用。
参数定义的栓许必须为:必选参数、默认参数、可变参数、关键字参数。
参数总结
对于任意函数,都可以通过类似 func(*args, **kw) 的形式调用它。