给定一个数集A,对A施加对应法则f,记作f(A),得到另一数集B,也就是B=f(A),这个关系式叫函数关系式
,简称函数
。
函数的作用:
函数是组织好的,可以重复使用的、用来实现单一功能的代码
函数的组成
数学函数 y = 6 * x + 9,x 是自变量,6 * x + 9 是执行过程,y 是因变量,自变量 x 决定了因变量 y 的值。
那么,你可以将 y = 6 * x + 9 看作三个部分。
在 Python 中,我们遇到过很多函数,有负责输入输出的函数、有负责数据处理的函数、当然也有其他的各种函数。
以上就是我们见过的 Python 的函数,这些函数是 Python 自带的函数,我们不需要管这些函数怎么来的,就直接拿来用就好了,这些函数也叫内置函数。
定义函数是将一段有规律的
、重复的
代码定义为函数,在下一次使用的时候直接调用,从而提高代码的重复利用率。
我们以上面 y = 6 * x + 9 为例,定义一个函数。
第一行: def 的全称是 define , 译为定义;fun 是函数名字,自己起的;(x) 这里是函数的参数,参数名字也是自己起;不要忘了最后的冒号 “ : ”
注意:函数不一定有参数,但是使用 def 的函数一定要有名字。而且符号都是用的英文的哦!
第二行:def 下一行缩进的内容叫做函数体,这是函数要实现的功能。即根据 x 的值,计算 6 * x + 9 ,将结果赋值给 y 。
第三行:return 语句是返回的意思,可以指定函数执行完毕后最终会得到什么样的结果,否则计算机是无法判断出函数最终要输出什么结果的。
代码片段:
# 函数名: 1.名字能体现函数的功能,一般用小写英文字母和数字、英文下划线组合使用
# 2.不能与 Python 内置函数重名
def function(x):
# 函数参数: 1.根据函数功能,括号内可以有多个参数,也可以没有参数
# 2.参数的命名规则与函数名命名规则一样
# 3.括号是英文括号,后面是英文冒号
y = 6 * x + 9
# 函数体:函数执行过程,完成函数功能,要缩进哦
return y
# return 返回值:需要返回什么数据,就写什么数据,如果不需要,可以不写
def math(x):
y = 30 + 11 * x
return y
定义了函数,并没有使用函数,所以终端中没有任何内容。
调用函数也就是执行函数,Python的函数,只是定义的话并不会执行,还需要调用。
基本语法格式:
函数名(参数列表)
说明:
要调用的函数名称必须是已经创建好的,参数列表中如果需要传递多个参数值,则各参数值间使用英文的逗号“,”分割,如果该函数没有参数,则直接写一对小括号即可。
代码示例:
def math(x):
y = 30 + 11 * x
return y
res = math(10)
print(res)
#运行结果为:140
解读分析:math(10) 就是调用函数,math 为定义函数的名字(定义与调用时名字一致);
传递参数,10 对应函数参数 x , 在调用函数时,将 10 传递给 x ;
在函数体中,y = 30 + 11 * 10 ,得出 y 的结果为 140 ;
那么,res 就用来接收 y 的值,即 res = 140 。所以,打印出来的结果就是 140。
练习:定义一个函数,用户传入 “ XXX ” ,就打印出 “ 您好,欢迎来到永和大王餐厅,您点的餐为 XXX ” 。这个 XXX , 可以传入牛肉面、卤肉饭,任何内容。
提示:使用 input ,接收用户输入内容,然后调用函数,完成功能。
food = input("请问您想吃什么 ? 请输入:")
def cook(x): #定义函数
str = '您好,欢迎来到永和大王餐厅,您的点餐为' + x
return str
res = cook(food) #调用函数
print(res)
运行结果为:
形参和实参
形参:形式参数,定义方法时定义的参数
实参:实际参数,也就是调用方法时实际传入的参数
多个参数同时传入的时候,形参和是实参是按照先后顺序一一对应的,实参的个数不能多也不能少。
在 Python 江湖中,函数中无论设置、传递多少个参数都可以,哪怕不设置、传递参数也行。
无参数
def hello():
print('爱')
print('好好磨')
print('永和大王豆浆一杯 6 元')
hello()
#运行结果为:
爱
好好磨
永和大王豆浆一杯 6 元
即使没有参数,在定义函数、调用函数的时候也不能省略括号。
函数的执行过程,可以有返回值,也可以没有返回值
。视情况而定。多个参数
def menu(noodle, drink, snacks):
print('面类选择:' + noodle)
print('饮料选择:' + drink)
print('小食选择:' + snacks + '\n')
menu('牛肉面','豆浆','油条')
menu('猪排面','果茶','小酥肉')
menu('雪菜肉丝面','豆浆','鸡腿排')
运行结果为:
注意:无论有多少个参数,调用函数时传递参数
的顺序要与定义
函数时设置参数
的顺序一致
。
在函数定义时,给某个参数指定默认值,当缺少该参数时,程序会使用函数设置的默认值传给形式参数。
语法格式:
def 函数名(参数1,参数2……,[参数N=默认值]):
函数体
def menu(noodle, drink, snacks='红糖糍粑'):
print('面类选择:' + noodle)
print('饮料选择:' + drink)
print('小食选择:' + snacks + '\n')
menu('牛肉面','豆浆')
menu('猪排面','果茶')
menu('雪菜肉丝面','豆浆')
运行结果为:
在这里,我们设置了默认参数 snacks = ‘红糖糍粑’ ,在调用函数的时候,红糖糍粑也会默认添加到菜单中。
当然了,如果有的顾客不想吃红糖糍粑,他就想吃油条怎么办。那就按顾客的来,顾客是上帝嘛。
def menu(noodle, drink, snacks='红糖糍粑'):
print('面类选择:' + noodle)
print('饮料选择:' + drink)
print('小食选择:' + snacks + '\n')
menu('牛肉面','豆浆')
menu('猪排面','果茶')
menu('雪菜肉丝面','豆浆','油条')
运行结果为:
在调用函数时,参数将逐个传递;在第三次调用函数menu(‘雪菜肉丝面’,‘豆浆’,‘油条’)时,‘油条’会替换默认的参数 ‘红糖糍粑’,将 snacks 设置为’油条’ 。
指不定长参数也叫可变参数,即传入函数中的实际参数可以是任意多个。
def menu(*food):
return food
order1 = menu('牛肉面','豆浆')
order2 = menu('猪排面','果茶','小酥肉','豆浆')
order3 = menu('雪菜肉丝面','豆浆','油条','猪排面','果茶')
print(order1)
print(order2)
print(order3)
print(type(order1))
print(type(order2))
print(type(order3))
运行结果为:
代码解读
:这里使用一个星号 * 加上参数名
就接收
到了所有参数
,无论参数写几个,都能接收到。而返回值就是参数名
。
我们将返回的内容打印出来,又打印了一下返回值的类型: < class ‘tuple’ >
Tuple 叫做元组,元组的写法是将所有内容放在小括号中,使用逗号隔开,和列表用法类似。但是又与列表不同,列表中的元素可以更改,而元组中的元素不可以更改
。
和列表相同的是:元组也是可以遍历的对象。使用 for 循环遍历一下。
def menu(*food):
for i in food:
print('点餐内容:' + i)
menu('牛肉面','豆浆')
menu('猪排面','果茶','小酥肉','豆浆')
menu('雪菜肉丝面','豆浆','油条','猪排面','果茶')
运行结果为:
(1)一个星号“*”
:所有实参以元组的方式传入函数,操作的时候直接将传入的参数当做一个元组来处理就行了
# 可变参数
# print(100,"abc",True,False) #可变参数的例子
# 声明可变参数的方法是,在参数前加”*“
# 1.加一个星号
def test1(*m): #定义可变参数的函数,在参数前加上’*‘
print(m)
test1(100)
test1(100,"abc",True,[11,22,33],(44,55,66))
def test2(*n):
sum = 0
for i in n:
sum += i
print("和为",sum)
# print("和为:",sum(n))
test2(100,100,100)
(2)两个星号“**”
:函数中所有的实参都被当做一个字典传入,操作的时候直接将传入的参数当做一个字典来处理就行了
#2.加两个星号
def test4(**args):
print(args)
test4(张三=18,李四=99)
运行结果为:
思考:def test5(a,*b,**c),哪个参数传给了a,哪个参数传给了b,哪个参数传给了c
test5(11,22,33,44,55,x=1,y=2,k=3)
def test5(a,*b,**c):
print(a)
print(b)
print(c)
test5(11,22,33,x=1,y=2,k=3) #11传给了a,22,33,44,55传给了b,x=1,y=2,k=3传给了c
python 使用 lambda 来创建匿名函数。
语法
lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
代码示例:
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print("相加后的值为 : ", sum(10, 20) )
print("相加后的值为 : ", sum(20, 20))
#可以通过变量来调用 ,如果将匿名函数赋值给变量,可以将变量当作函数来调用
运行结果为:
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
(1)返回一个值: return后面给一个数据,调用时只能使用一个变量来接
def test(str0): #定义方法
if str0=="买到了":
return 1
else:
return 0
x = test("买到了")
print(x)
结果为:1
(2)返回多个值: return后面给多个数据,调用时可以使用多个变量来接
函数,不仅可以支持多个参数,还可以支持多个返回值。
例如:我们要做优惠活动,到店顾客,只要买单我们就有美食相送。具体规则如下:用户消费满 69 元,我们随机赠送 10 元小食一份;用户消费 99 元,我们随机赠送 10 元小食外加一个冰激淋。
import random
foodten = ['油条','小酥肉','鸡腿排']
def order(money):
if money > 99:
a = random.choice(foodten)
return a,'冰激淋'
elif 69 < money < 99:
b = random.choice (foodten)
return b
else:
return '不好意思,您的消费达不到优惠活动'
print(order(50))
print(order(70))
print(order(130))
运行结果为:
在这里,有 3 条 return 语句,每条语句的返回内容都是不一样的,返回的数量也不一样,这就是返回多个值的用法。
def test(a,b): #定义方法 这个方法实现的功能将两个值交换
x=a
a=b
b=x
return a , b #return 值返回两个
m=test(100,1000) #调用函数 用一个容器去接多个值,多个值以元组的方法返回
print(m) #结果为(1000, 100)
i,j=test(10,20)
# print(i,j)
print(i)
print(j)
#运行结果为:
#(1000, 100)
#20
#10
return特征:
1.可以为当前函数执行完毕返回一个结果
2.执行之后,函数则会终止
3.一个函数可以书写多个return语句,但一般会放入分支结构中
4.一个函数若要返回多个数据,可借助复合数据类型(list, tuple,set, dict)
多函数协作
在开始的时候,我们说过,函数封装了独立功能,一个程序往往由多个函数来配合实现。 当多函数协作时,就涉及到函数中的一个非常重要的内容 – 变量作用域。
rule = '所有餐厅都要卖【兰州拉面】'
def YH():
rule_yh = '所有永和大王餐厅卖烤串'
print('永和大王:%s'%rule)
print('永和大王:%s'%rule_yh)
def ZGF():
print('真功夫:%s'%rule)
print('真功夫:%s'%rule_yh)
YH()
ZGF()
运行结果为:
单独运行 YH() 函数没有任何问题;运行 ZGF() 函数就报错了;
这个代码给我们弹出了一个 bug ,在 print(‘真功夫:%s’%rule_yh)
在这句代码中,抛出 NameError: name ‘rule_yh’ is not defined 的错误。
这就是变量作用域的问题;
作用域分为全局作用域
和局部作用域
。
全局作用域:在所有函数之外赋值的变量,可以在程序的任意位置使用(全局作用域),就是全局变量;
比如第一行的 rule = ‘所有餐厅都要卖【兰州拉面】’;它在 YH() 与 ZGF() 两个函数中都起作用。
局部作用域:在某个函数内部赋值的变量,只能在当前函数内使用(局部作用域),出了这个函数,它就不起作用了,这就是局部变量;
比如 rule_yh = ‘所有永和大王餐厅卖烤串’;它只在 YH() 函数中起作用,在 ZGF() 就不起作用了。
可是,如果我非要让 rule_yh = ‘所有永和大王餐厅卖烤串’ ,在真功夫中起作用怎么办?
有办法,在 rule_yh = '所有永和大王餐厅卖烤串’使用global
对变量进行修饰,global 表示全局意思
,它就告诉计算机,这个变量变成了全局变量,它在任何地方都起作用。
rule = '所有餐厅都要卖【兰州拉面】'
def YH():
global rule_yh
rule_yh = '所有永和大王餐厅卖烤串'
print('永和大王:%s'%rule)
print('永和大王:%s'%rule_yh)
def ZGF():
print('真功夫:%s'%rule)
print('真功夫:%s'%rule_yh)
YH()
ZGF()
运行结果为:
其实,我们早就见过了函数嵌套,比如:print(len(‘我爱你’))、print(type(10)) 等。
这就是 print() 函数嵌套了 len() 函数,print() 函数嵌套了 type() 函数;这样,代码会先执行 print() 括号内部的函数,在将这个函数结果放入 print() 函数中执行,打印出来。
这样操作叫做在函数内部调用其他函数
,我们自己定义的函数也可以这么做。
def hello():
print('欢迎光临永和大王')
print('很高兴为您服务')
def order():
print('这里是下单中心')
hello()
print('请您点餐')
print('以上菜单的菜品都有')
order()
运行结果为:
在这里,我定义了两个函数,函数 hello() 与函数 order() ,在函数 order() 中调用了函数 hello() ,这样函数 hello() 中的代码会在函数 order() 中运行。
这就是函数的嵌套,在一个函数中调用其他函数。
在数学与计算机科学中指在函数的定义中使用函数自身的方法。
特性:
1.必须有一个明确的结束条件。
2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
3.相邻两次重复之间有紧密的联系,前一次要为后一次做准备,通常前一次的输出就是作为后一次的输入。
利用递归函数计算1~100相加之和:
def sum(n): #定义递归函数进行求和
if n > 0:
return n + sum(n-1) #递归调用
else:
return 0
print('1到100相加之和为:',sum(100))
#运行结果为:
#1到100相加之和为: 5050
阶乘
def JC(n):
ji = 1
for i in range(1,n+1):
ji *= i
return ji
print(JC(3))
#执行结果为:6
累加
def leijia(n):
if n < 1000:
return n + leijia(n+1) # 5*4*3*2*1 递归函数 函数自己调用自己
else:
return 0
print(leijia(998))
# print(leijia(1)) # 传1-2会报错 python循环不能超过997次
#执行结果为:1997