函数 function
什么是函数: 函数是可以重复执行的语句块,可以重复使用 函数是面向过程编程的最小单位
函数的作用: 1.用于封装语句块,提高代码的重用性 2.定义用户级别的函数
def 语句 (把编码打包) call(调用)
语法: def函数名(形参列表): 语句块(代码块) 说明: 1.函数的名字就是语句块的名称 2.函数名的命名规则与变是一名相同(函数名必须为标识符) 3.函数名是一个变量(不要轻易对其赋值) 4.函数有自己的名字空间,在函数外部不可以访问函数内部的变量(注意)在函数内部可以访问函数外部的变量,要让函数处理外部的数据需要传入一些数据 5.函数如果不需要传入参数,则参数列表可以为空 6.语句部分不能为空,如果为空需要填充pass语句 作用: 用于创建函数,用函数名这个变量绑定这个函数
# 示例见:
# 此示例示意用def语句定义一个没有参数的函数
def say_hello():
print("hello world!")
print("hello china!")
print("hello tarena!")
函数的调用表达式: 函数名(实际调用传递参数) 说明: 函数调用是一个表达式 如果没有return语句,函数执行完毕后返回None对象
# 示例见:
# 此示例示意用def语句来定义带有参数的函数
# 此函数名为mymax,有两个形式参数a,b 用于接收实参的传递
# 此函数计算两个参数的最大值并打印
def mymax(a,b):
print("a=",a)
("b=",b)
if a>b:
print(a,"大于",b)
else:
print(a,"小于",b)
mymax(100,200) #函数调用
练习:
# 3 写一个函数myadd,此函数中的参数列表里有两个参数x,y此函数的功能是打印 x+y的和
# 如:
# def myadd(...):
# ...# ... 部分自己实现
# myadd(100,200) #打印300
# myadd("ABC","123") #打印 ABC123
def myadd(x,y):
z = x +y
print("和是",z)
myadd(100,200) # 打印 300
myadd("ABC","123") # 打印ABC123
# 写一个函数print_event,传入一个参数n代表终止的整数,打印0~n 之间所有的偶数
# 如:
# def print_event(n):
# ....此处自己完成
# print_even(10)
# 打印:
# 0 2 4 6 8
# 方法1
def print_event(n):
for x in range(n):
if x % 2==0:
print(x)
print_event(10)# 方法2
def print_event(n):
for x in range(0,n+1,2):
print(x)
print_event(10)
return 语句:
语法: return[表达式] 注:[]代表其中的内容可省略 作用: 用于函数中,结果当前函数的执行,返回到调用该函数的地方,同时返回一个对象的引用关系 说明: 1.return 语句先执行右侧的表达式,再将表达式的执行结果送回给当前函数的调用者 2.return 语句右侧的表达式可以省略,省略后相当于 return None 3.如果函数内没有return语句,则函数执行完最后一条语句后返回None) (相当于在最后加了一条return None语句)
# 示例见:
# 此示例示意return语句在函数中的应用
def say_hello2():
print("hello aaa")
print("hello bbb")
#return 1+ 2 #等同于 return None
return [1,2,3,4,5]
print("hello ccc")
v = say_hello2()
print("v=",v)
v2 = say_hello2()
print("v2=",v2)
练习:
# 1.写一个函数mymax,实现返回两个数的最大值:
# 如:
# def mymax(a,b):
# ...
# print(mymax(100,200))#200
# print(mymax(100,200))#ABCD
# 方法1
def mymax(a,b):
s = max(a,b)
return s
print(mymax(100,200))
print(mymax("ABC","ABCD"))
# 方法2
def mymax(a,b):
zuida = a
if b > zuida:
zuida = b
return zuida
print(mymax(100,200))
print(mymax("ABC","ABCD"))
# 2.写一个函数myadd,实现给出两个数,返回这个两个数的和
# 如:
# def myadd(x,y):
....
# a = int(input("请输入第一个数:")
# b = int(input("请输入第二个数:")
# print("你输入的两个数的和是:",myadd(a,b))
def myadd(x,y):
return x+y
a = int(input("请输入第一个数:"))
b = int(input("请输入第二个数:"))
print("你输入的两个数的和是:",myadd(a,b))
# 3.写一个函数,input_number
# def input_number():
# ...# 此处自己实现,此函数返回列表
# 此函数用来获取用户循环输入往返整数,当用户输入负数时结束输入
# 将用户输入的数字以列表的形式返回,再用内建函数max,min,sum
# 求出用户输入的最大值,最小值以及和
# L = input_number()
# print("用户输入的最大数是:",max(L))
# print("用户输入的最小数是:",min(L))
# print("用户输入的全部数的和是:",sum(L))
def input_number():
# 1.创建空列表
l = []
# 2.循环读取用户输入的正整数,存入在述列表
while True:
n = int(input("请输入用户数字:"))
if n<0:
break# 此处自己实现,此函数返回列表
l.append(n)
# 3.返回上述列表的引用关系
return l
L = input_number()
print("用户输入的最大数是:",max(L))
print("用户输入的最小数是:",min(L))
print("用户输入的全部数的和是:",sum(L))
python函数的参数传递(把数据给函数)
传递方式: 位置传参 序列传参 关键字传参 字典关键字传参
位置传参: 实际参数(实参)的对应关系与形式参数(形参)的对应关系是按位置来依次对应的 示意:
def mymin(a,b,c)
pass
mymin(1,2,3)
说明: 实际参数和形式参数通过位置进行传递和匹配 实际参数的个数必须与形式参数的个数相同
# 示例:
# 此示例示意位置传参
def myfunl(a,b,c):
"这是一个函数的传参的示例"
print("a的值是:",a)
print("b的值是:",b)
print("c的值是:",c)
myfunl(1,2,3) # 1 --- a 2 ----b 3----c
myfunl(4,5,6)
序列传参 序列传参是指在函数调用过程中,用*将序列拆解后按位置进行传递的 传参方式
# 示例见:
# 此示例示意序列传参
def myfunl(a,b,c):
"这是一个函数的传参的示例"
print("a的值是:",a)
print("b的值是:",b)
print("c的值是:",c)
l1=[11,22,33]
t2=(100,200,300)
s3="ABC"
myfunl(l1[0],l1[1],l1[2]) # li[0](将11)---> a, L1[1]
myfunl(*l1) # 等同于myfunl(l1[0],l1[1],l1[2])
myfunl(*t2)
myfunl(s3[0],s3[1],s3[2])
myfunl(*s3)
# 说明:
# 序列传参时,序列拆解的位置将与形参一一对应
关键字传参: 关键字传参是指传参时,按着形参的名称给形参赋值 实参和形参按名称进行匹配
# 示例见;
# 此示例示意关键字传参
def myfunl(a,b,c):
"这是一个函数的传参的示例"
print("a的值是:",a)
print("b的值是:",b)
print("c的值是:",c)
myfunl(c=3,a=1,b=2)
myfunl(c=33,a=11,b=22+3)
# 说明:
# 实参和形参接形参名进行匹配,可以不接位置进行匹配
字典关键字传参: 是指实参为字典,将字典用**拆解后进行关键字传参的传参方式
# 示例见;
def myfunl(a,b,c):
"这是一个函数的传参的示例"
print("a的值是:",a)
print("b的值是:",b)
print("c的值是:",c)
d1 = {"c":33,"a":11,"b":22}
myfunl(c=d1["c"],a=d1["a"],b=d1["b"]) #33---->c,11---->a
myfunl(**d1) #拆解字典,在按关键字传参方式传递
# 说明:
# 字典的键名和形参名必须一致
# 字典的键名必须为符合标识符命名规则的字符串
# 字典的键名要在形参中存在
练习:
# 已知有列表:
L = [1,2,True,None,3.14]
# 调用print函数,打印用“#”号分隔的文字信息到终端上
print(...) #打印 1#2#True#None#3.14
l = [1,2,True,None,3.14]
print(*l,sep="#")# 打印 1#2#True#None#3.14
函数的综合传参: 1.函数的传参方式,在能确定形参能唯一匹配到相应实参的情况下可以任意组合 2.函数的位置传参要先于关键字传参
# 示例:
def myfun1(a,b,c)
pass
myfun1(100,c=300,b=200) #正确
myfun1(c=300,b=200,100) #错的
myfun1(100,*[200,300]) #正确
myfun1(*[100,200],300) #正确
myfun1(100,*[200],300) #正确
myfun1(100,**{"c":300,"b":200}) #正确
myfun1(**{"c":300,"b":200},a=100) #正确
# 可变 和 不可变的类型的容器作为实参传递的区别:
# 可变类型的实参作为参数传递时,在函数内部可以改变容器内的数据
# 示例见:
# 此示例示意,当函数的实参为可变数据类型时,在函数内部可以改为容器的内容
l = [1,2,3,4]
t = (1.1,2.2,3.3,4.4)
def append_5(x):
# x.append(5)
x += (5,)#新的x元组
append_5(l)
print(l)
append_5(t) #不存在
print(t)
练习
# 写一个函数,此函数读取用户输入的数据,最后保存于全局变量的列表
# l中,当用户输入小于零的数时结束输入
l=[]
def input_number(l1):
while True:
x = int(input("请输入:"))
if x<0:
break
l1.append(x)
input_number(l)
print(l)
input_number(l)
print(l)
以下讲函数的定义(创建函数的def语句的形参列表)
# 函数的缺省参数:
# 语法:
# def 函数名(形参名1 = 默认实参1,形参2=默认实参2,...):
# 语句块
# 示例见:
def info(name,age=1,address="不详"):
print(name,"今年",age,"岁.家庭住址",address)
info("路飞",35,"北京市朝阳区")
info("tarena",15)
info("小飞")
说明: 缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其 右侧的所有参数都必须有缺省参数,如: def test_fn(a,b=10,c): 是错的 缺省参数可以有0个,1个或多个,甚至全部都有缺省参数
# 示例:
def fn(a,b=10,c):# 错误
pass
def fn(a=0,b=10,c=20) # 这是对的
pass
练习:
# 写一个函数myadd,此函数可以计算两个数,三个数及四个数的和
def myadd(...):
....
print(myadd(10,20))#30
print(myadd(100,200,300))#600
print(myadd(1,2,3,4))#10
def myadd(a,b,c=0,d=0):
return a + b+ c +d
print(myadd(10,20))
print(myadd(100,200,300))
print(myadd(1,2,3,4,))
函数形参的定义方式:
1.位置形参 2.型号的元组形参 3.命名关键字形参 4.双星号字典形参
# 位置形参
# 语法:
# def 函数名(形参名1,形参名2...):
# 语句块
# 星号无组形参:
# 语法:
# def 函数名(*元组形参名):
# 语句块
# 作用:
# 收集多余的位置传参
# 说明:
# 在一个函数定义中元组形参名最多只能有一个,一般命名为"args"
# 示例见:
# 此示例示意星号元组形参的定义和使用
def func(*args):
print("实参个数是",len(args))
print("args=",args)
func(1,2,3,4)
func(5,6,7,8,"A","B","C","D")
func()
练习:
# 写一个函数 mysun 可以传入任意个数字实参,返回所有实参的和
# def mysum(*args):
# ...
# print(mysum(1,2,3,4))
# print(mysum(,1,3,5,7,9))
# 方法1
def mysum(*args):
s = 0
for x in args:
s +=x
return s
print(mysum(1,2,3,4))
print(mysum(1,3,5,7,9))
# 方法2
def mysum(*args):
return sum(args)
print(mysum(1,2,3,4))
print(mysum(1,3,5,7,9))
命名关键字形参
# 语法:
# def 函数名(*,命名关键字形参1,命名关键字形参2,...):
# 语句块
# 或
# def 函数名(*args,命名关键字形参1,命名关键字形参2,..)
# 语句块
# 作用:
# 强制所有的参数都必须用关键字传参或字典关键了传参
# 示例见:
# named_keyword_args.py
# 此示例示意在函数形参中定义命名关键字形参,强制让函数调用使用命名# 关键字传参:
def funcl(a,b,*,c,d):
print(a,b,c,d)
funcl(1,2,3,4) # 报错
funcl(1,2,c=30,d=40)
funcl(a=10,b=20,c=30,d=40)
def funcl(a,b,*args,c,d):
print(a,b,args,c,d)
funcl(1,2,3,4) # 报错
funcl(1,2,c=30,d=40)
funcl(a=10,b=20,c=30,d=40)
funcl(1,2,3,4,d=400,c=300)
funcl(*"ABCDEFG",**{"c":999,"d":888})
双星号字典形参
# 语法:
# def 函数名(**字典形参名)
# 语句块
# 作用:
# 收集多余的关键字传参
# 说明:
# 字典形参名一般命名"kwargs"
# 一个函数内字典形参最多只能有一个
# 示例见:
# 此示例示意用双星号字典形参接收多余的关键字传参
def func(**kwargs):
print("关键字传参的个数是:",len(kwargs))
print("kwargs=",kwargs)
func(name="weimingze",age=35,address="北京时朝阳区")
func(a=1,b=2)
def func(a,b,**kwargs):
print("关键字传参的个数是:",len(kwargs))
print("kwargs=",kwargs)
func(a=1,b=2,c=3)
# 函数的参数说明:
# 位置形参,缺省参数,星号元组形参,双星号字典形参可以混合使用
函数参数自左自右的顺序为:
# 1.位置形参
# 2.星号元组形参
# 3.命名关键字形参
# 4.双星号字典形参
# 示例:
def fn(a,b=20,*args,c=30,d=40,**kwargs):
pass
fn(1)
fn(100,200,300,400,c="C",d="D",e="E")
练习:
# 已知内建函数max帮助文档为:
# max(...)
# max(iterable) -> value
# max(arg1,arg2,*args) -> value
# 仿造 max写一个mymax函数,功能与max完全相同
#(要求不允许调用max')
# 测试程序如下:
# print(mymax([6,8,3,5])) #8
# print(mymax(100,200)) #200
# print(mymax(1,3,5,7,9)) #9
# 方法1
def mymax(*args):
if len(args)==1: #判断是否是一个可迭代参数的情况
l = args[0] #一定绑定一个可迭代对象
zuida = l[0]
for x in l:
if x >zuida:
zuida = x
return zuida
else: #否则有多个参数的情况
zuida = args[0]
for x in args:
if x>zuida:
zuida = x
return zuida
print(mymax([1,3,5,7,9]))
print(mymax(100,200))
print(mymax(6,8,3,5))
# 方法2
def mymax(a,*args):
if len(args)==0: #判断是否是一个可迭代参数的情况
l = a #一定绑定一个可迭代对象
zuida = l[0]
for x in l:
if x >zuida:
zuida = x
return zuida
else: #否则有多个参数的情况
zuida = a
for x in args:
if x>zuida:
zuida = x
return zuida
全局变量和局部变量
局部变量:local varible: 定义在函数内部的变量称为局部的变量(函数的形参也是局部变量) 局部变量只能在函数内部使用 局部变量在函数调用时才能够被创建,在函数调用之后会自动销毁 当有同名的全局变量和局部变量时,优先访问局部变量
全局变量:global variable: 定义在函数外部,模块内部的变量称为全局变量 全局变量,所有函数都可以直接访问(但函数内不能将其直接赋值)
局部变量说明: 在函数内部赋值语句不会对全局变量造成影响 局部变量只能在其被声明的函数内部访问,而全局变量可以在整数模块范围内访问
# 示例见:
# global_local.py
# 此示例示意全局变量的定义和局部变量的定义
a = 100
b = 200
c = 999999
def fx(c):
a = 1 # 创建局部变量,并没有改变全局变量
d = 400
print(a,b,c,d)
fx(300)
print("a=",a)
print("b=",b)
print("c=",c)
# globals 和 locals 函数:
# globals() 返回当前全局作用域内变量的字典
# locals() 返回当前局部作用域内变量的字典
# 示例见:
# globals_and_locals.py
# 此示例示意全局变量的定义和局部变量的定义
a = 100
b = 200
c = 999999
def fx(c):
a = 1 # 创建局部变量,并没有改变全局变量
d = 400
print(a,b,c,d)
fx(300)
print("a=",a)
print("b=",b)
print("c=",c)
# 此示例示意globals 和 locals 函数的使用方法
a = 1
b = 2
c = 3
def fn(c,d):
e = 300
# 此处有多少个局部变量?
print("locals()返回:",locals())
# 此处有多少个全局变量?
print("locals()返回:",globals())
print(c)
print(globals()["c"])
fn (100,200)