参考学习书籍《零基础入门学习python》作者小甲鱼
函数可以理解为打包代码还能在需要的时候调用(代码块的变量)且可以传入参数
创建函数和调用函数
创建函数使用def():括号和冒号都是英文环境下的
调用函数使用函数名加小括号
def add():#创建一个叫add的函数
print("你好python")#执行内容
print("我是函数属于python学习的进阶")
print("我还会计算:1+1=",1+1)
add()#调用函数
你好python
我是函数属于python学习的进阶
我还会计算:1+1= 2
参数:
def add(eve):
print(f"我喜欢学习{eve}")
add("python")
我喜欢学习python
实际参数(实参),形式参数(形参) 实参就是真正传入的值,例如上面传入的python 形参就是要传入的值,例如上面的eve
(1).位置参数和关键字参数,默认参数
def add(a,b):
print(f"我是{b},我是{a}")
add("齐","喾")#位置参数,位置为默认定义函数的位置
我是齐,我是喾
add(b="喾",a="齐")#关键字参数
我是齐,我是喾
"""
关键字参数不能在位置参数之前
"""
def add(a,b=10):#默认参数b=10
c=a+b
return c #返回值,这里返回c的值
add(12,22) #a=12,b=22返回值为34
34
add(12) a=12,b为默认参数10
22
"""
默认参数要定义在最后面的位置
"""
例子:sum(iterable, /, start=0)#限制左侧不能使用关键字参数
"""
斜杠的左侧不能使用关键字参数,右边随便
"""
例子:def add(a,*b,c):
print(a,b,c)
这里的*左边随意,右边必须是关键字参数
(2):收集参数:
def az(*q):#收集参数在形参前面加一个*且打包在一个元组里面
print("这里有{}个参数".format(len(q)))
print(type(q))
az(1,2,3,4,5)
这里有5个参数
<class 'tuple'>
#####对比
def add(eve):
print(f"我喜欢学习{eve}")
print("这里有{}个参数".format(len(eve)))
print(type(eve))
add("python")
我喜欢学习python
这里有6个参数
<class 'str'>
"""
收集参数后面还有参数的话调用时要使用关键字参数
"""
###使用一个*是收集返回一个元组,两个**是收集返回一个字典
def ch(x,*y,**z):
print(x,y,z)
ch(1,2,3,a=1,b=34)
1 (2, 3) {'a': 1, 'b': 34}
(3):解包:
x=1,2,3,4
def ad(a,b,c,d):
print(a,b,c,d)
ad(*x)#将整个x放如函数
1 2 3 4
zc={'a':1, 'b':2, 'c':3, 'd':4}
def ad(a,b,c,d):
print(a,b,c,d)
ad(**zc)#返回字典的值
1 2 3 4
ad(*zc)#返回字典的键
a b c d
作用域:
def ad():
x=123
print(x)
ad()#调用函数
>>123
print(x)
>>name 'x' is not defined#x没有被定义
x=123#定义了全局变量,可以在函数内部调用可以在函数外部调用
def ad():
print(x)
ad()
>>123
print(x)
>>123
a=12
def ad():
a=123
print(a)
ad()
>>123
print(a)
>>12
global语句:函数内部外部有两个同名变量且值不相同的变量,global会将函数外部的值修改为函数内部的值,且在外部 打印时返回函数内部的值
a=123
def ad():
global a
a=12
print(a)
ad()
>>12
print(a)
>>12
4.嵌套函数
def add():
x=12
def ad():
x=223
print(x)
ad()
print(x)
add()
>>12
>>223
"""
直接调用ad的话会报错,要在函数内部调用
"""
nonlocal语句:修改函数内部的同名变量的值使其相等
def add():
x=12
def ad():
nonlocal x
x=223
print(x)
ad()
print(x)
add()
>>223
>>223
LEGB法则 L:局部作用域 E:嵌套函数的外层函数的作用域 G:全局作用域 B:内置作用域
闭包
def add(x):
def ad(y):
return y**x#ad函数内部返回算法
return ad #add函数内部调用返回算法值
q=add(2) #闭包原理使其外层函数保存数值其值参与后期计算(下同)
w=add(10)
print(q(2))
>>4
print(w(2))
>>1024
函数调用函数
def add():
print("我是add")
def ad(a):
print("哈喽我是ad")
a()
print("I LOVE python")
ad(add)
>>哈喽我是ad
我是add
I LOVE python
装饰器
import time
def ch(fun):
print("我是齐喾")
a=time.time()
fun()
b=time.time()
print("我来自甘肃天水")
print(f"此程序执行共消耗时间{(b-a):.2f}秒")
@ch#装饰器就是把下面要执行的代码块作为上面函数的参数运行@就是语法糖
def ad():
time.sleep(2)
print("我来自天水秦州")
ad=ch(ad) #装饰器原来的样子执行效果和上面的一样位置不一样程序效率低
我是齐喾
我来自天水秦州
我来自甘肃天水
此程序执行共消耗时间2.02秒
def add(fun):
def ad():
x=fun()
return x+1
return ad
def ads(fun):
def ad():
x=fun()
return x*x*x
return ad
def access(fun):
def ad():
x=fun()
return x*x
return ad
@add
@ads
@access
def az():
return 2
print(az())
>>65
#由此可知语法糖是倒执行的,他先执行access,再执行ads,最后执行add
#装饰器传递参数
import time
def logger(msg):
def add(fun):
def call():
a=time.time()
fun()
b=time.time()
print(f"[{msg}]一共消耗时间为{(b-a):.2f}")
return call
return add
#@logger(msg="A")
def funA():
time.sleep(1)
print("正在调用A....")
#@logger(msg="B")
def funB():
time.sleep(2)
print("正在调用B....")
funA=logger(msg="A")(funA)
funB=logger(msg="B")(funB)
funA()
funB()
"""
装饰器有闭包(嵌套)经过装饰器执行程序要重新调用函数
没有嵌套直接执行程序
"""
5.lambda一行流函数
格式:lambda 传入的参数:返回值
lambda是一个表达式不是语句,他可以出现再python语法不允许def语句出现的地方,lambda只能做简单的函数,只是一个匿名函数
a=lambda y,x:y**x
a(2,10)
>>1024
y=[lambda x:x*x,2,3]
y[0](y[1])
>>4
y[0](y[2])
>>9
6.递归----高级循环
def funa(x):#定义函数
if x>0: #设置递归约束条件
print("你好世界")#递归内容
x=x-1#设置递归退出条件
funa(x)#递归
funa(5)#调用递归
你好世界
你好世界
你好世界
你好世界
你好世界
def feib(x):
if x==1 or x==2:
return 1
else:
return feib(x-1)+feib(x-2)
print(feib(10))
>>55