1、函数的定义及调用 y=f(x)
函数是一段代码的表示
def <函数名>(<参数(0个或多个)>)
<函数体>
return <返回值>
库函数:input、print、type等
计算n!
def fact(n):
s = 1
for i in range(1,n+1):
s *=i
return s
a = fact(6)
print(a)
-函数定义时,所指定的参数是一种占位符
-函数定义后,如果不经过调用,不会被执行
-函数定义时,参数是输入、函数体是处理、结果是输出(IPO)
2、函数的参数传递
形参:形式参数,写在函数定义处的参数。
实参:实际参数,写在函数调用处的参数。
位置参数:函数定义时没有默认值的参数,也叫必传参数;调用时的实参必须与形参一一对应。
默认参数:函数定义时有默认值的参数,调用时可以不传递参数;默认参数必须写在最后。
关键字参数:在函数调用时指定参数的名字,参数的位置就无所谓了。
可变长度参数
# 默认值参数必须写在最后面
def show(a, b=5):
print('a:', a)
print('b:', b)
# 指定名字后,参数的顺序就无所谓了
# show(b=3, a=2)
# 可变长度参数
def var_len_args(a, b, *arg, **kwarg):
print(a, b)
# 是一个元组,存放多传的位置参数
print(arg)
# 是一个字典,存放多传的关键字参数
print(kwarg)
var_len_args(1, 2, 3, 4,5,6, name='二狗', age=18)
# *的使用
def test(a, b):
print(a, b)
lt = [1, 2]
# 可以这样使用,但是参数多的时候有点不太好用
# test(lt[0], lt[1])
# *可以将一个序列中的元素展开,以上式等价
test(*lt)
def test2(aa, bb):
print(aa, bb)
d = {'aa': 250, 'bb': 200}
# test2(aa=d['aa'], bb=d['bb']) #设置的形参要与字典中的键保持一致!!!
# **可以将字典中的键值对展开,作为关键字参数,以上式等价
test2(**d)
运行结果:
1 2
(3, 4, 5, 6)
{'name': '二狗', 'age': 18}
1 2
250 200
(1)参数个数
函数可以有参数,也可以没有,但必须保留括号
def <函数名>():
<函数体>
return <返回值>
def fact():
print("我也是函数")
(2)可选参数传递
函数定义时可以为某些参数指定默认值,构成可选参数
def <函数名>(<非可选参数>,<可选参数>):
<函数体>
return <返回值>
def fact(n,m=1):
s = 1
for i in range(1,n+1):
s *= i
return s//m
>>>fact(10)
3628800
>>>fact(10,5)
725760
函数定义时可以设计可变数量参数,既不确定参数总数量
def <函数名>(<参数>,*b):
<函数体>
return <返回值>
def fact(n,*b):
s =1
for i in range(1,n+1):
s *= i
for item in b:
s *= item
return s
>>>fact(10,3)
10886400
>>>fact(10,3,5,8)
435456000
(3)参数传递的两种方式
函数调用时,参数可以按照位置或名称方式传递
def fact(n,m=1):
s = 1
for i in range(1,n+1):
s *= i
return s//m
>>>fact(10,5) #位置传递
725760
>>>fact(m=5,n=10) #名称传递
725760
3、函数的返回值
(1)函数可以返回0个或多个结果
-return保留字用来传递返回值,可以传递任意多个或0个
-函数可以有返回值,也可以没有,可以有 return ,也可以没有
# 无参无返回值
def print_ten_hello():
for i in range(10):
print('Hello world!')
# print_ten_hello()
# 带参无返回值,可以指定默认值
def print_n_hello(n=10):
for i in range(n):
print('Hello world!')
# print_n_hello()
# 带参有返回值
def add(a, b):
ret = a + b
# 函数返回值,没有返回值的函数默认返回None
return ret
# 执行return函数立即结束并返回,后面的代码不会执行
a += 1
ret = add(3, 5)
print(ret)
# 没有返回,默认返回None
print(print_ten_hello())
运行结果:
8
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
None
(2)函数调用时,参数可以按照位置或名称方式传递
def fact(n,m=1):
s = 1
for i in range(1,n+1):
s *= i
return s//m,n,m
>>>fact(10,5)
(725760,10,5) #元组类型
>>>a,b,c = fact(10,5)
>>>print(a,b,c)
725760 10 5
函数进阶
函数的定义位置是随意的吗?
不是,一定要先定义再调用,也就是说调用一定要放在定义之后
函数的名字是否可以相同?
不可以,虽然语法不报错,但是后者会覆盖前者
函数中能否再定义一个函数?
可以,函数内部定义的函数称为内部函数,它是很多高级功能的基础
4、局部变量和全局变量
程序全局变量、函数局部变量
n,s = 10,100 #n和s是全局变量
def fact(n):
s = 1 #fact()函数中的n和s是局部变量
for i in range(1,n+1) :
s *= i
return s
print(fact(n),s) # n和s是全局变量
>>>3628800 100
(1)规则一:局部变量和全局变量是不同变量
(觉得是这个样子)函数内部同名变量是一个变量,外部变量和函数内部变量不是一个
-局部变量是函数内部的占位符,与全局变量可能重名但不同
-函数运算结束后,局部变量被释放
-可以用global保留字在函数内部使用全局变量
n,s = 10,100 #n和s是全局变量
def fact(n): #fact()函数中使用global保留字声明
global s #此处s是全局变量s
for i in range(1,n+1) :
s *= i
return s #此处s指全局变量s
print(fact(n),s) #此处全局变量s被函数修改
运行结果:362880000 362880000
global:
# 全局变量:定义在函数外部的变量,拥有全局的作用域
num = 125
# print(num)
def show():
global num
# 全局变量只能使用,不能修改
# 直接赋值不是修改全局变量,而是定义一个同名的局部变量
'''若想要修改全局变量,想要使用global进行声明,若想改变内部函数的内部函数的...同变量,
每层都global 同变量下去,编写一下理解吧'''
def test():
global num
num = 20
print(num)
test()
show()
print(num)
运行结果:
20
nonlocal:
def wai():
n = 100
def nei():
# 可以使用外部函数的局部变量,但是不能修改
# 直接赋值相当于重新定义了一个局部变量
''' 若想修改,效益使用nonlocal进行声明,若函数最内层定义一个 nonlocal变量可改变最外层函数内部所有同名变量值'''
nonlocal n
n = 10
print(n)
nei()
print(n)
wai()
(2)规则二:局部变量为组合数据类型且未创建,等同于全局变量
ls = ["F","f"] #通过使用[]真实创建了一个全局变量列表ls
def func(a):
ls.append(a) #此处ls是列表类型,未真实创建,则等同于全局变量
return
func("C") #全局变量ls被修改
print(ls)
运行结果:['F', 'f', 'C']
ls =["f","F"] #通过使用[]真实创建了一个全局变量列表ls
def func2(a):
ls = [] #此处ls是列表类型,真实创建,ls是局部变量
ls.append(a)
func2("C") #局部变量ls被修改
print(ls)
运行结果:['f', 'F']
(3)使用规则
-基本数据类型,无论是否重名,局部变量与全局变量不同
-可以通过global保留字在函数内部声明全局变量
-组合数据类型,如果局部变量未真实创建,则是全局变量
附:块级作用域
if True:
a = 250
#代码块外面可以使用,说明没有块级作用域
print(a)
5、lambda函数(匿名函数)
(1)函数可以像普通函数一样赋值
def test():
print('for test')
# 获取函数的名字
print(test.__name__)
# 函数可以像普通变量一样进行赋值
a = test
print(a.__name__)
# 同样可以调用
a()
(2)函数可以作为另一个函数的参数
# 函数作为另一函数的参数
def demo(func):
func()
demo(test)
(3)lambda函数返回函数名作为结果
-lambda函数是一种匿名函数,即没有名字的函数
-使用lambda保留字定义,函数名是返回结果,不需要return返回
-lambda函数用于定义简单的、能够在一行内表示的函数
<函数名> = lambda <参数>:<表达式>
#等价于:
def <函数名>(<参数>):
<函数体>
return <返回值>
#pycharm:
f = lambda x,y:x+y
print(f(10,15))
f1=lambda:"lambda函数"
print(f1())
#python:
>>>f = lambda x,y:x+y
>>>f(10,15)
25
>>>f =lambda:"lambda函数"
>>>print(f())
lambda函数
def calc(a, b, suanfa):
return suanfa(a, b)
def add(x, y):
return x + y
print(calc(3, 5, add))
# 通过匿名函数实现,更加方便简洁
print(calc(3, 5, lambda x, y: x + y))
# lt = [1, 4, 9, 7, 5, 2, 3]
lt = [
{'name': 'ergou', 'age': 18, 'weight': 60},
{'name': 'dagou', 'age': 19, 'weight': 65},
{'name': 'erhua', 'age': 16, 'weight': 50},
{'name': 'dahua', 'age': 20, 'weight': 55},
]
def key(d):
return d['age']
#两种方式:1、def定义函数调用 2、lambda
#lt.sort(key=key)
lt.sort(key=lambda d: d['weight'])
for i in lt:
print(i)
(4)谨慎使用lambda函数
-lambda函数主要用作一些特定函数或方法的参数
-lambda函数有一些固定使用方式,建议逐步掌握
-一般情况,建议使用 def 定义的普通函数
小结:
-使用保留字 def 定义函数, lambda 定义匿名函数
-可选参数(赋初值)、可变参数(*b)、名称传递
-保留字 return 可以返回任意多个结果
-保留字 global 声明使用全局变量,一些隐式规则
6、闭包使用
闭包可以看做是具有执行环境的函数
- 外部函数中定义一个内部函数
- 内部函数中使用外部函数变量
- 外部函数将内部函数作为返回值返回
- 返回的函数就叫闭包
def wai(n):
# 定义内部函数
def nei():
# 使用外部函数的局部变量
return n * n
# 函数作为返回值返回
return nei
# 返回的就是闭包
f1 = wai(10)
f2 = wai(5)
print(f1())
print(f2())
7、装饰器
作用:当需要修改函数的功能,有无法/不想修改原来的函数时,通过装饰器进行解决
使用:
- 装饰器就是一个函数,该函数具有一个我参数(函数类型),返回一个闭包
- 在闭包中调用传递进来的函数,在调用函数的前后就可以添加内容了
def zhuangshiqi(func):
def wrapper():
print('======')
func()
print('******')
return wrapper
@zhuangshiqi # 等价于:test = zhuangshiqi(test)
def test():
print('for test')
# test()
# test = zhuangshiqi(test)
test()
运行:
======
for test
******
标准装饰器:可以任意类型的函数(参数、返回值不限制)
def zhuangshiqi(func):
# 接纳任意的参数形式
def wrapper(*args, **kwargs):
print('xxx')
ret = func(*args, **kwargs)
print('yyy')
# 返回对应的返回值
return ret
return wrapper
@zhuangshiqi
def test(n):
print('My lucky number is {}'.format(n))
return n * n
print(test(7))
运行结果:
xxx
My lucky number is 7
yyy
49