Learn day4 函数参数\变量\闭包\递归

1.函数描述

# ### 函数 
"""
(1)函数的定义:功能 (包裹一部分代码 实现某一个功能 达成某一个目的)
(2)函数特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理
"""# (3) 函数的基本格式
"""
# 函数的定义处
def func():code1....code2....# 函数的调用处
func()
"""
# 函数的定义处
def func():print("今天是好日子")# 函数的调用处
func()# (4) 函数的命名
"""函数的命名
字母数字下划线,首字符不能位数字
严格区分大小且,且不能使用关键字
函数命名有意义,且不能使用中文哦驼峰命名法:
(1)大驼峰命名法:每个单词的首字符大写 (一般在类中起名用这样的方式, 推荐)mycar => MyCar   busstop => BusStop myhouse => MyHouseyoucanyouupnocannobb => YouCanYouUpNoCanNoBb
(2)小驼峰命名法:除了第一个单词首字符不用大写之外,剩下首字符都大写                 (函数中的命名)mycar => myCar  myhouse=>myHousemycar => my_car  myhouse => my_house (推荐)
"""# 函数的定义处
def cheng_fa_biao_99():for i in range(9,0,-1):for j in range(1,i+1):print("{:d}*{:d}={:2d} ".format(i,j,i*j),end="")print()# 函数的调用处
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()
# cheng_fa_biao_99()for i in range(10):cheng_fa_biao_99()

2.函数参数

# ### 函数的参数 : 函数运算时,需要的值
"""
参数:形参: 形式参数 (在函数的定义处)实参: 实际参数 (在函数的调用处)形参:(普通[位置]形参 , 默认形参 , 普通收集参数 , 命名关键字参数, 关键字收集参数)
实参:(普通实参.关键字实参)形参 和 实参 要一一对应
"""# (1) 普通形参
# 函数的定义处 hang,lie 普通形参
def small_start(hang,lie):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印换行print()i+=1
# 函数的调用处  3,8 普通实参
small_start(3,8)# (2) 默认形参 hang,lie 在函数定义处给与默认值
"""如果给与实参,那么就使用实际参数,如果没给实参,那么就使用参数的默认值
"""
def small_start(hang=10,lie=10):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印换行print()i+=1
# small_start()
small_start(4,9)# (3) 普通形参 + 默认形参 
"""默认形参必须写在普通形参的后面,语法上有要求"""
# 函数的定义处
def small_start(hang,lie=10):
# def small_start(hang,lie=10):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印换行print()i+=1
# 函数的调用处
# small_start(3)# small_start(4,8)# small_start() error  # 形参实参要一一匹配# (4) 关键字实参
"""
(1)如果使用关键字实参进行函数调用,实参的顺序无所谓
"""
"""
(2)如果定义时是普通形参,调用时是关键字实参,
那么这个参数后面的所有调用方式都需要关键字实参进行调用
"""
def small_start(hang,a,b,c,lie=10):
# def small_start(hang,lie=10):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印换行print()i+=1
# 关键字实参 hang  和 lie 
# small_start(lie = 12,hang = 12)# small_start(3,4,5,6,7)
small_start(3,c=90,b=7,a=5,lie =14)

 3.收集参数

# ### 收集参数
"""
收集参数:(1) 普通收集参数 * 在函数的定义处专门用来收集那些多余的,没人要的普通实参,形成一个元组语法:def func(*args) : args => arguments
def func(*args):print(args) => 返回的数据类型是元组
"""
def func(a,b,c,*args):print(a,b,c)print(args)func(1,2,3,4,5,6,6,7,8,8,8,8,8,9)# 计算任意长度的累加和
def mysum(*args):total = 0for i in args:total += iprint(total)
mysum(11,23,45,56,1,2)
"""
收集参数:(2) 关键字收集参数 ** 在函数的定义处专门用来收集那些多余的,没人要的关键字实参,形成一个字典语法:def func(**kwargs) : kwargs => keyword arguments
def func(**kwargs):print(kwargs) => 返回的数据类型是字典
"""
def func(a=1,b=2,**kwargs):    print(a,b)print(kwargs)# 方法1
func(99,b=99,c=4,d=90,f=78)
# 方法2
func(b=99,a=111,c=4,d=90,f=78)# 拼接任意字符串
dictvar = {"monitor"}
def func(**kwargs):str1 = ""str2 = ""dictvar = {"monitor":"班长","classflower":"班花"}for k,v in kwargs.items():print(k,v)if k in dictvar:str1 += dictvar[k]+":"+ v  + "\n"else:            str2 += v + " "print(str1)print("吃瓜群众:",str2)func(monitor="舒则会",classflower="郭一萌",eatgua1="黄花",eatgua2="李村海")

 5.命名关键词参数

# ### 命名关键字参数
"""
(1) def func(a,b,*,参数1,参数2....) 在*后面定义的参数就是命名关键字参数
(2) def func(*args,参数,**kwargs) 夹在普通收集参数和关键字收集参数之间的是命名关键字参数
如果是命名关键字参数,必须使用关键字实参来进行调用赋值
"""# 定义方法1
def func(a,b,*,c,d):print(a,b)print(c,d)func(1,2,c=3,d=4)# 定义方法2
def func(*args,c,**kwargs):print(args)print(c)print(kwargs)func(1,2,3,4,a=1,b=2,c=3)# 定义方法3
def func(a,b,*,c=3):print(a,b)print(c)
# func(1,2)
func(1,2,c=22)# 区别于默认形参
def func(a,b,c=3):print(a,b)print(c)
# 三种方式皆可
func(1,2)
func(1,2,c=22)
func(1,2,22)# ### * 和 ** 的魔术用法
"""在函数的定义处:* ** 相当于打包操作 (一个是元组,一个是字典)在函数的调用处:* ** 相当于解包操作 (把里面的元素一个一个拿出来,当成实参调用赋值了)
"""
# *
def func(a,b,c):print(a,b,c)lst = [1,2,3]
func(*lst)  # 相当于 func(1,2,3) 把列表里面的每一个元素都单独拿出来当成参数进行函数的调用# **
print('--------->')
def func(a,*,b,c,d):    print(a)print(b,c,d)dictvar = {"b":2,"c":3,"d":4}
func(1,**dictvar) # 相当于 func(1,b=2,c=3,d=4) 把字典里面的每一个键值对,都拿出来,变成键=值的形式,进行关键字实参赋值操作# 扩展
# 函数的定义处def func(a,b,*,c,d):    print(a,b)print(c,d)
lst = [1,2]
dictvar = {"c":3,"d":4}
# 函数的调用处
func(*lst,**dictvar)"""
在字典的前面加上一个*号,默认只传递键.
一个*号 后面可以跟str list tuple set dict 常用的一般就是list
二个**  后面可以跟dict 把键值对变成键=值得形式进行函数调用.
"""def func(a,b):print(a,b)
dictvar = {"c":3,"d":4}
func(*"pa")"""
函数的定义处:参数的定义有顺序:
普通形参 -> 默认形参 -> 普通收集参数 -> 命名关键字参数 -> 关键字收集参数def func(*args,**kwawrgs):这样的形式定义函数,可以接收到所有种类的参数;pass
"""# 参数练习:
def f1(a, b, c=0, *args, **kw):print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)def f2(a, b, c=0, *, d, **kw):print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)#(一)
# f1(1, 2) # a=1,b=2,c=0,args=(),kw={}
# f1(1, 2, c=3) #a=1,b=2,c=3,args=(),kw={}
# f1(1, 2, 3, 'a', 'b') # a=1,b=2,c=3,args=(a,b),kw={}
# f1(1, 2, 3, 'a', 'b', x=99)#a=1,b=2,c=3,args=(a,b),kw={x:99}
# f2(1, 2, d=99, ext=None)#a=1,b=2,c=0,d=99,kw={ext:None}#(二)
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
# f1(1,2,3,4,d=99,x="#")
f1(*args, **kw) #a=1,b=2,c=3,args=(4,),kw={'d':99,x:'#'}#(三)
myargs = (1, 2, 3)
mykw = {'d': 88, 'x': '#'}
f2(*myargs, **mykw) #a=1,b=2,c=3,d=88,kw={x:'#'}#(四) a b 普通形参  c 默认形参 *args 普通收集参数 d 命名关键字参数 kw 关键字收集参数
def f1(a, b, c=0, *args,d,**kw):print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)print(d)f1(1,2,3, 'a', 'b',d=67, x=99,y=77) #a=1,b=2,c=3,d=67,args=(a,b),kw={,x:99,y:77}

 5.return 返回值

# ### return 函数的返回值,只出现在函数里
"""
return 自定义返回值,如果没有写return ,默认返回None
功能:把值返回到函数的调用处;
(1)return 后面可以返回值 是自定义的. 除了6大标准数据类型之外,还有类 对象 函数 
(2)如果执行了return 语句,意味着函数终止,后面的代码不执行
"""
# (1) return 后面可以返回值 是自定义的. 除了6大标准数据类型之外,还有类 对象 函数 
def func():# return 1# return 3.14# return 3+4j# return True# return [1,2,3]# return {"a":1,"b":2}pass
res = func() # res ={"a":1,"b":2}
print(res)res = print(1)
print(res)# (2) 如果执行了return 语句,意味着函数终止,后面的代码不执行def func():print("这句话执行了1")print("这句话执行了2")return 1print("这句话执行了3")print("这句话执行了4")
res = func()
print(res)
print("<============>")
def func():for i in range(5):if i == 3:return iprint(i)
res = func()# 0 1 2# (3) 计算器小例子
def calc(sign,num1,num2):if sign == "+":res = num1 + num2elif sign == "-":res = num1 - num2elif sign == "*":res = num1 * num2elif sign == "/":if num2 == 0:return "除数不能为0"res = num1 / num2return resprint("<===>")
res = calc("+",1,1)
res = calc("-",-1,90)
res = calc("*",52,10)
res = calc("/",52,10)
res = calc("/",5200,10)
print(res)

 6.函数名的使用

# ### 1.函数名的使用 
# 1.函数名是个特殊的变量,可以当做变量赋值
def func():print("函数名可以当成变量使用")abc = 45
abc = func
print(abc)
abc()# 2.函数名可以作为容器类型数据的元素
def func1():print(1)
def func2():print(2)
def func3():print(3)lst = [func1,func2,func3]
for i in lst:i() # func1() func2() func3()# 3.函数名可以作为函数的参数
def func1(func):func()def func2():print('woshi func2')# func形参接收到了func2这个实参函数,调用func1执行里面的代码块.调用func2()
func1(func2)print("<===>")# 4.函数名可作为函数的返回值
def func3(func):return funcdef func4():print("woshi func4")# func4这个实参被func接收到 ,执行func3代码块内容,直接return func4 ,res接收到了返回值func4
res = func3(func4)
res() # func4()# ### 2.__doc__或者help查看文档
# help(print)
res = print.__doc__
print(res)# 如何自定义函数的文档
# 吃大肠的过程
def eat_big_chang(something):"""功能:模拟吃大肠的过程参数:大肠返回值:吃没吃完的状态    """print("我是在模拟{}过程".format(something))print("第一步.找肠子头")print("第二步.把肠子头放嘴里")print("第三步.使劲唆")return "擦擦嘴,满意的放下肠子.吃完了"eat_big_chang("吃大肠")# 方法1 用 函数.__doc__
res = eat_big_chang.__doc__
print(res)# 方法2
print("<===>")
help(eat_big_chang)

 7.全局变量与局部变量

# ### 全局变量 与 局部变量
"""
局部变量:定义在函数内部的变量
全局变量:定义在函数外部或者用global关键字在函数内部定义的变量作用域: 作用的范围局部变量的作用域:只限定在函数内部;
全局变量的作用域:横跨整个文件
"""# 1.局部变量的获取 与 修改
def func():a = 15# 获取局部变量print(a)# 修改局部变量a = 17print(a)
func()
# print(a) error  a局部变量值限定在函数内部使用;# 2.全局变量的获取 与 修改
b = 100
# 获取全局变量
print(b)
# 修改全局变量
b += 200
print(b)print("<====>")
# 3.在函数内部可以直接获取全局变量,但是不能直接修改
# 用global关键字,修改全局变量
c = 50
def func():global cprint(c)c = 60print(c)
func()
print(c)# 4.在函数内部可以直接定义一个全局变量
def func():global dd = 90
func()
print(d)# 总结:
"""
global关键字 如果函数外部没有该变量,就是在函数内部定义一个全局变量
global关键字 如果函数外部有该变量,那么就是在函数内部修改一个全局变量
global用来修饰全局变量 ; 有就修改,没有就创建.
"""
# ### 全局变量 与 局部变量
"""
局部变量:定义在函数内部的变量
全局变量:定义在函数外部或者用global关键字在函数内部定义的变量作用域: 作用的范围局部变量的作用域:只限定在函数内部;
全局变量的作用域:横跨整个文件
"""# 1.局部变量的获取 与 修改
def func():a = 15# 获取局部变量print(a)# 修改局部变量a = 17print(a)
func()
# print(a) error  a局部变量值限定在函数内部使用;# 2.全局变量的获取 与 修改
b = 100
# 获取全局变量
print(b)
# 修改全局变量
b += 200
print(b)print("<====>")
# 3.在函数内部可以直接获取全局变量,但是不能直接修改
# 用global关键字,修改全局变量
c = 50
def func():global cprint(c)c = 60print(c)
func()
print(c)# 4.在函数内部可以直接定义一个全局变量
def func():global dd = 90
func()
print(d)# 总结:
"""
global关键字 如果函数外部没有该变量,就是在函数内部定义一个全局变量
global关键字 如果函数外部有该变量,那么就是在函数内部修改一个全局变量
global用来修饰全局变量 ; 有就修改,没有就创建.
"""

 8.函数的嵌套

# ### 函数的嵌套
"""
函数之间允许嵌套:嵌套在外层的就是外函数嵌套在内容的就是内函数
"""def outer():def inner():print("111")inner()"""
(1)内部函数可以直接在函数外部调用么 不行
(2)调用外部函数后,内部函数可以在函数外部调用吗  不行
(3)内部函数可以在函数内部调用吗  可以
(4)内部函数在函数内部调用时,是否有先后顺序 在定义在调用
python 没有预加载机制:即不能提前把函数加载到内存当中.
"""
outer()"""def func():passfunc()int a = 5 cint a = 6 java$a = 67 phpvar a = 89 jsa = 90 python
"""# 外层是outer函数,里面有inner , inner 中还有smaller ,如果调用smaller?def outer():    def inner():def smaller():print(id)print("我是smaller函数")smaller()inner()
outer()# LEGB 原则 (就近找变量原则)
"""
#找寻变量的调用顺序采用LEGB原则(即就近原则)
B —— Builtin(Python);Python内置模块的命名空间      (内建作用域)
G —— Global(module); 函数外部所在的命名空间        (全局作用域)
E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
L —— Local(function);当前函数内的作用域            (局部作用域)
依据就近原则,从下往上 从里向外 依次寻找
"""# 生命周期
"""
内置命名空间中的所有变量 > 全局命名空间中的所有变量 > 局部命名空间中的所有变量
"""# 了解
"""
# 命名空间 : 划分一块区域保存所有数据,以字典的方式存储(变量与值形成映射关系).一共三种.
(1)内建命名空间:解释器启动时创建,直到解释器运行结束,生存周期最长
(2)全局命名空间:文件运行时创建,直到解释器运行结束,生存周期较长
(3)局部命名空间:函数调用时,里面的局部变量才创建,调用结束后即释放,生存周期较短
#命名空间的提出是为了划分和控制变量是否可见,以及生存周期的长短.#命名空间 创建顺序:(了解)python解释器启动->创建内建命名空间->创建全局命名空间->创建局部命名空间
#命名空间 销毁顺序:(了解)函数调用结束后->销毁函数对应的局部命名空间数据->销毁全局命名空间数据->销毁内建命名空间数据
""""""
# 地址相关知识点:-5~正无穷 int浮点型非负数 float相同的布尔值  bool在实数+虚数结构中永远不相同(只有虚数部分除外) complex相同的字符串 str空元组 tupleid() 用来获取地址is  / is not 针对于地址提出来,用来判断两个变量地址是否相同.var1 = 90var2 = 90print(id(var1))print(id(var2))
"""

 9.nonlocal

# ### nonlocal 用来修饰局部变量
"""
nonlocal 符合LEGB 原则, 就近原则找变量;
(1) nonlocal 用来修改局部变量
(2) nonlocal 会不停的寻找上一层空间所对应的值,拿来修改
(3) 如果上一层找不到,继续向上寻找,再也找不到了,直接报错;
"""# (1) nonlocal 只能用来修改局部变量
a = 90
def func():# nonlocal a  errora = 80print(a)
func()# (2) nonlocal 会不停的寻找上一层空间所对应的值,拿来修改
"""通过LEGB原则,可以获取到上一层空间的值,只能单纯的获取,不能直接修改
如果想要修改 通过nonlocal 加以修饰.
"""
def outer():a = 20def inner():nonlocal aprint(a)a += 1print(a)inner()
outer()# (3) 如果上一层找不到,继续向上寻找,再也找不到了,直接报错; nonlocal 只能修饰局部变量
a = 100def outer():a = 100def inner():# a = 110def smaller():nonlocal aa += 10# print(a)
        smaller()print(a,"<=1=>")inner()print(a,"<=2=>")
outer()# (4) 不通过nonlocal 是否可以改变局部变量? 可以! 需要使用列表进行操作;
def outer():lst = [100,101,102]def inner():lst[0] += 1inner()print(lst)
outer()

 10.闭包函数

# ### 闭包函数
"""
概念:内函数使用了外函数的局部变量,
并且外函数把内函数返回出来的过程,叫做闭包
这个内函数叫做闭包函数
"""# (1) 基本语法:
def lizuqing_family():    father = "李嘉诚"def father_say():print("{}说了:先定他一个小目标,买一个英国伦敦".format(father))return father_sayfunc = lizuqing_family() # func = father_say
print(func)
func() #=> father_say()# (2) 闭包函数的升级
"""
内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长了该变量的生命周期
"""
def liaopingping_family():jiejie = "马蓉"meimei = "马诺"money = 1000def jiejie_hobby():nonlocal moneymoney -= 500print("买名牌包包,名牌手表,名牌狗链,.....家里的前还剩下%s"%(money))def meimei_hobby():nonlocal moneymoney -= 400print("宁愿在宝马里面哭,也不愿再自行车上面撒欢.家里的钱还剩下%s"%(money))def big_guanjia():return jiejie_hobby,meimei_hobby # 返回一个元组# return (jiejie_hobby,meimei_hobby)return big_guanjiafunc = liaopingping_family()
print(func)
tup = func()
print(tup) #(<function liaopingping_family.<locals>.jiejie_hobby at 0x000001DCD2877048>, <function liaopingping_family.<locals>.meimei_hobby at 0x000001DCD28770D0>)
# 调用 姐姐jiejie_hobby
jiejie =  tup[0]
print(jiejie) #<function liaopingping_family.<locals>.jiejie_hobby at 0x0000026526B49048>
jiejie()
# 调用 妹妹meimei_hobby
meimei = tup[1]
meimei()  # <function liaopingping_family.<locals>.meimei_hobby at 0x000001DCD28770D0>

 10.闭关函数

# ### 闭包的特点
"""内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长了该变量的生命周期
"""
def outer(val):def inner(num):return num +  valreturn innerfunc = outer(10)
res = func(5) # func = inner() = num + val = 10 + 5 = 15
print(res)
"""
func = outer(10)
val 接收到10这个值 return inner 
因为内函数使用了外函数的局部变量val,val就与内函数发生绑定,延长该变量生命周期,不释放,等待下一次调用时使用res = func(5)
num 接受到5这个值 return num + val return 5 + 10  => return 15
"""# ### 闭包的意义
"""
闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
模拟一个鼠标点击计数功能:
"""clicknum = 0
def clickfunc():global clicknumclicknum += 1print(clicknum)# 模拟点击操作,点击一次就调用一次
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clicknum = 100
clickfunc()# 用闭包函数来进行改造
def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func
clickfunc2 = clickfunc()
clickfunc2() # clickfunc2() = func()
clickfunc2() 
clickfunc2() 
clickfunc2() 
clickfunc2() 
x = 100
clickfunc2() 

11.闭包的特点

# ### 闭包的特点
"""内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长了该变量的生命周期
"""
def outer(val):def inner(num):return num +  valreturn innerfunc = outer(10)
res = func(5) # func = inner() = num + val = 10 + 5 = 15
print(res)"""
func = outer(10)
val 接收到10这个值 return inner 
因为内函数使用了外函数的局部变量val,val就与内函数发生绑定,延长该变量生命周期,不释放,等待下一次调用时使用res = func(5)
num 接受到5这个值 return num + val return 5 + 10  => return 15
"""# ### 闭包的意义
"""
闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
模拟一个鼠标点击计数功能:
"""clicknum = 0
def clickfunc():global clicknumclicknum += 1print(clicknum)# 模拟点击操作,点击一次就调用一次
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clicknum = 100
clickfunc()# 用闭包函数来进行改造
def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func
clickfunc2 = clickfunc()
clickfunc2() # clickfunc2() = func()
clickfunc2() 
clickfunc2() 
clickfunc2() 
clickfunc2() 
x = 100
clickfunc2() 

 11.闭包的特点

# ### 闭包的特点
"""内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长了该变量的生命周期
"""
def outer(val):def inner(num):return num +  valreturn innerfunc = outer(10)
res = func(5) # func = inner() = num + val = 10 + 5 = 15
print(res)"""
func = outer(10)
val 接收到10这个值 return inner 
因为内函数使用了外函数的局部变量val,val就与内函数发生绑定,延长该变量生命周期,不释放,等待下一次调用时使用res = func(5)
num 接受到5这个值 return num + val return 5 + 10  => return 15
"""# ### 闭包的意义
"""
闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
模拟一个鼠标点击计数功能:
"""clicknum = 0
def clickfunc():global clicknumclicknum += 1print(clicknum)# 模拟点击操作,点击一次就调用一次
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clicknum = 100
clickfunc()# 用闭包函数来进行改造
def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func
clickfunc2 = clickfunc()
clickfunc2() # clickfunc2() = func()
clickfunc2() 
clickfunc2() 
clickfunc2() 
clickfunc2() 
x = 100
clickfunc2() 
# ### 闭包的特点
"""内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长了该变量的生命周期
"""
def outer(val):def inner(num):return num +  valreturn innerfunc = outer(10)
res = func(5) # func = inner() = num + val = 10 + 5 = 15
print(res)"""
func = outer(10)
val 接收到10这个值 return inner 
因为内函数使用了外函数的局部变量val,val就与内函数发生绑定,延长该变量生命周期,不释放,等待下一次调用时使用res = func(5)
num 接受到5这个值 return num + val return 5 + 10  => return 15
"""# ### 闭包的意义
"""
闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
模拟一个鼠标点击计数功能:
"""clicknum = 0
def clickfunc():global clicknumclicknum += 1print(clicknum)# 模拟点击操作,点击一次就调用一次
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clickfunc()
clicknum = 100
clickfunc()# 用闭包函数来进行改造
def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func
clickfunc2 = clickfunc()
clickfunc2() # clickfunc2() = func()
clickfunc2() 
clickfunc2() 
clickfunc2() 
clickfunc2() 
x = 100
clickfunc2() 

 12.locals和globals

# ### locals 和 globals
""" 
locals() 获取当前作用域的所有变量如果locals在函数外:所获取的是locals(),打印返回值之前的所有内容
如果locals在函数内:所获取的是locals(),调用之前所有内容
"""# 当前作用域在全局范围
a = 1
b = 2
res = locals()
c = 3
print(res)"""
# 当前作用域在局部范围
zz = 90
def func():d = 4f = 5res = locals()g = 6print(res)func()
"""
"""
globals 无论在函数内外,都只获取全局作用域当中的所有内容如果globals在函数外:所获取的是globals(),打印返回值之前的所有内容
如果globals在函数内:所获取的是globals(),调用之前所有内容
"""
# 当前作用域在全局范围
a = 1
b = 2
res = globals()
c  = 3
print(res)# 当前作用域在局部范围
'''
aa = 11
bb = 22
def func():d =1 f = 2res = globals()z = 3print(res)
cc = 33
func() #res = globals()
dd = 4
'''# globals 动态的创建全局变量
"""
globals() 返回的是系统的字典,只需要在字典里面添加键值对,就可以创建全局变量
字典中的键 就是变量名
字典中的值 就是变量所指代的值
"""
dic = globals()
print(dic)
dic["wangwen"] = "风流倜傥,美若天仙,才华横溢,玉树临风"
# wangwen = "风流倜傥,美若天仙,才华横溢,玉树临风"
print(wangwen)# globals 批量创建全局变量
# 创建p1~p5 5个全局变量
def func():dic = globals()for i in range(1,6):# p1 ~ p5 5个键dic["p%d" % (i)] = ifunc()
print(p1)
print(p2)
print(p3)
print(p4)
print(p5)
# ### locals 和 globals
""" 
locals() 获取当前作用域的所有变量如果locals在函数外:所获取的是locals(),打印返回值之前的所有内容
如果locals在函数内:所获取的是locals(),调用之前所有内容
"""# 当前作用域在全局范围
a = 1
b = 2
res = locals()
c = 3
print(res)"""
# 当前作用域在局部范围
zz = 90
def func():d = 4f = 5res = locals()g = 6print(res)func()
"""
"""
globals 无论在函数内外,都只获取全局作用域当中的所有内容如果globals在函数外:所获取的是globals(),打印返回值之前的所有内容
如果globals在函数内:所获取的是globals(),调用之前所有内容
"""
# 当前作用域在全局范围
a = 1
b = 2
res = globals()
c  = 3
print(res)# 当前作用域在局部范围
'''
aa = 11
bb = 22
def func():d =1 f = 2res = globals()z = 3print(res)
cc = 33
func() #res = globals()
dd = 4
'''# globals 动态的创建全局变量
"""
globals() 返回的是系统的字典,只需要在字典里面添加键值对,就可以创建全局变量
字典中的键 就是变量名
字典中的值 就是变量所指代的值
"""
dic = globals()
print(dic)
dic["wangwen"] = "风流倜傥,美若天仙,才华横溢,玉树临风"
# wangwen = "风流倜傥,美若天仙,才华横溢,玉树临风"
print(wangwen)# globals 批量创建全局变量
# 创建p1~p5 5个全局变量
def func():dic = globals()for i in range(1,6):# p1 ~ p5 5个键dic["p%d" % (i)] = ifunc()
print(p1)
print(p2)
print(p3)
print(p4)
print(p5)

 13.匿名函数

# ### 匿名函数  => lambda 表达式 
"""
lambda 表达式: 用一句话来表达只有返回值的函数 
好处:简洁,方便,定义函数快速简单
语法:lambda 参数 : 返回值
"""
# 1.无参的lambda表达式
def func():return 123456func = lambda : 123456
res = func()
print(res)# 2.有参的lambda表达式
def func(n):return type(n)
res = func("1234")
print(res)func = lambda n : type(n)
res = func([1,2,3])
print(res)# 3.带有条件判断的lambda表达式
def func(n):if n % 2 == 0:return "偶数"else:return "奇数"# 4.三目运算符: 用来表达双项分支
"""
真值 if 条件表达式 else 假值如果条件表达式成立,执行真值如果条件表达式不成立,执行假值
"""
n = 11
res = "偶数" if n % 2 == 0 else "奇数"
print(res)n = 90
func = lambda n : "偶数" if n % 2 == 0 else "奇数"
print( func(n) )# 计算参数中的最大值
def func(m,n):if m>n:    return melse:return n
print( func(13,9) )func = lambda m,n : m if m>n else n
print( func(-90,90) )

 14.递归函数

# ### 递归函数
"""
递归函数:自己调用自己的函数
递:去
归:回
一去一回是递归递归的最大深度:官网说法1000层,但实际996~1000
"""# 简单递归
def digui(n):print(n,"<==11==>")if n>0:digui(n-1)print(n,"<==22==>")
digui(5)"""
去的过程:n = 5print(5,"<==11==>")5 > 0 digui(5 - 1) digui(4)n = 4print(4,"<==11==>")4 > 0 digui(4 - 1) digui(3)n = 3print(3,"<==11==>")3 > 0 digui(3 - 1) digui(2)n = 2print(2,"<==11==>")2 > 0 digui(2 - 1) digui(1)n = 1print(1,"<==11==>")1 > 0 digui(1 - 1) digui(0)n = 0print(0,"<==11==>")0 > 0  条件不满足,往下执行print(0,"<==22==>")回的过程: (把剩下的没走玩的代码继续执行)回到上一次函数的调用处第17行,从17行继续向下执行n = 1 print(1,"<==22==>")回到上一次函数的调用处第17行,从17行继续向下执行n = 2 print(2,"<==22==>")回到上一次函数的调用处第17行,从17行继续向下执行n = 3 print(3,"<==22==>")回到上一次函数的调用处第17行,从17行继续向下执行n = 4 print(4,"<==22==>")回到上一次函数的调用处第17行,从17行继续向下执行n = 5 print(5,"<==22==>")递归函数彻底终止.
""""""
# 递归的最大深度 error
def func():func() #[Previous line repeated 995 more times]
func()
"""# 栈帧空间:是为了运行函数所需要开辟的空间
"""
(1)没调用一次函数,就是开辟一个栈帧空间的过程
每结束一次函数,就是释放一个栈帧空间的过程
递归函数就是不停的开辟栈帧空间和释放栈帧空间的过程(2)回的过程有两种触发时机:    (1)当最后一层函数全部执行完毕,触发回的过程,回到上一层函数调用处(2)当遇到return 返回值的时候,触发回的过程,回到上一层函数调用处(3)如果递归层数过大,不推荐使用递归,如果使用,务必添加一个跳出的条件,防止内存溢出;
""""""
# 栈帧空间彼此的数据是隔离的,彼此独立,各是各的空间
def abc(n)print(n)
abc(1)
abc(2)
"""# 计算n的阶乘 5! = 5*4*3*2*1
def jiecheng(n):if n<=1:return 1return n * jiecheng(n-1)
res = jiecheng(5)
print(res)"""
需要先把表达式的值算完之后,再返回# 去的过程
n = 5 return 5 * jiecheng(5 - 1) => 5 * jiecheng(4)
n = 4 return 4 * jiecheng(4 - 1) => 4 * jiecheng(3)
n = 3 return 3 * jiecheng(3 - 1) => 3 * jiecheng(2)
n = 2 return 2 * jiecheng(2 - 1) => 2 * jiecheng(1)
n = 1 n <= 1 满足 return 1# 回的过程
n = 2 return 2 * jiecheng(2 - 1) => 2 * jiecheng(1) => 2 * 1
n = 3 return 3 * jiecheng(3 - 1) => 3 * jiecheng(2) => 3 * 2 * 1
n = 4 return 4 * jiecheng(4 - 1) => 4 * jiecheng(3) => 4 * 3 * 2 * 1
n = 5 return 5 * jiecheng(5 - 1) => 5 * jiecheng(4) => 5 * 4 * 3 * 2 * 1
最后直接 return  5 * 4 * 3 * 2 * 1 = 120
"""
print(jiecheng(1))

 

转载于:https://www.cnblogs.com/NGU-PX/p/11217463.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 中去除字符串中空格的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1、方法分类 str.trim(); //去掉首尾空格str.replace(" ",""); //去除所有空格&#xff0c;包括首尾、中间str.re…

使用重定向的输入和输出创建子进程

本主题中的示例演示如何使用控制台进程中的CreateProcess函数创建子进程。它还演示了一种使用匿名管道重定向子进程的标准输入和输出句柄的技术。请注意&#xff0c;命名管道也可用于重定向进程I / O. 所述CreatePipe函数使用SECURITY_ATTRIBUTES结构来创建可继承句柄读写两个…

手动挡停车时挂档有技巧

徐小姐来电&#xff1a;我家的汽车要年检了&#xff0c;前几天&#xff0c;工作人员帮我把车子开进检测站去检测&#xff0c;开回来后停在原位上&#xff0c;然后把钥匙交给我。我拿钥匙一点火&#xff0c;车子就突然往前动了&#xff0c;根本没有时间反应&#xff0c;已经撞到…

LOJ 3156: 「NOI2019」回家路线

题目传送门&#xff1a;LOJ #3156。 题意简述&#xff1a; 有一张 \(n\) 个点 \(m\) 条边的有向图&#xff0c;边有两个权值 \(p_i\) 和 \(q_i\)&#xff08;\(p_i<q_i\)&#xff09;表示若 \(p_i\) 时刻在这条边的起点&#xff0c;则 \(q_i\) 时刻能到达这条边的终点。 你需…

线程池概述

线程池 一个线程池的工作线程代表应用程序的高效执行异步回调的集合。线程池主要用于减少应用程序线程的数量并提供工作线程的管理。应用程序可以对工作项进行排队&#xff0c;将工作与可等待的句柄相关联&#xff0c;根据计时器自动排队&#xff0c;并与I / O绑定。 线程池架…

WEB 请求处理二:Nginx 请求 反向代理

上一篇《WEB请求处理一&#xff1a;浏览器请求发起处理》&#xff0c;我们讲述了浏览器端请求发起过程&#xff0c;通过DNS域名解析服务器IP&#xff0c;并建立TCP连接&#xff0c;发送HTTP请求。本文将讲述请求到达反向代理服务器的一个处理过程&#xff0c;比如&#xff1a;在…

方向盘的正确驾驭方法

如果问您油门踏板和方向盘哪个与驾驶员最“亲密”&#xff0c;您会选择谁呢&#xff1f;恐怕还是方向盘吧。如果汽车行驶过程中您的双手同时离开了方向盘&#xff0c;那么事故的隐患也就随之而来。下面我们就为您全面介绍汽车方向盘的正确使用方法。专家介绍&#xff0c;握方向…

SQL server 2005中无法新建作业(Job)的问题

客户端是使用企业管理其&#xff08;Management Studio&#xff09;新建job&#xff0c;总是无法创建&#xff0c;查找了很多资料&#xff0c;有的说是需要sp2, 但有的又说不是... ... 没有时间去研究为什么&#xff0c;但确有一种方法解决&#xff1a;到服务器端去创建job&…

线程池API

线程池API 线程池应用程序编程接口&#xff08;API&#xff09;使用基于对象的设计。以下每个对象都由用户模式数据结构表示&#xff1a; 池对象是一组可用于执行工作的工作线程。每个进程可以根据需要创建具有不同特征的多个隔离池。每个进程都有一个默认池。清理组与一组回…

WEB 请求处理 一:浏览器 请求发起处理

最近&#xff0c;终于要把《WEB请求处理系列》提上日程了&#xff0c;一直答应小伙伴们给分享一套完整的WEB请求处理流程&#xff1a;从浏览器、Nginx、Servlet容器&#xff0c;最终到应用程序WEB请求的一个处理流程&#xff0c;前段时间由于其他工作事情的安排&#xff0c;一直…

离合器半联动探秘

离合器踏板作用是切断发动机和变速箱之间的动力&#xff0c;有利于起步、变速、和停车。那么如何更好的使用它呢&#xff1f; 离合器的五种状态示意图 离合器半联动的使用方法揭密如下&#xff1a; 离合器半联动的使用探密之一 将离合器抬到车开始动时你就别再抬了&#xff0c;…

Biztalk Server 2006安装配置

前段时间收到了来自beta.microsoft.com的BTS20006 Beta2的下载地址&#xff0c;这两天对它进行了一番安装配置。下面把一些经过和步骤和大家分享一下&#xff0c;手中有一些去年的Biztalk Server2004版本的培训资料&#xff0c;里面有11个Lab。需要的朋友请留下mail&#xff0c…

apache 官方 Dubbo 文档

只是分享、记录一下 dubbo 的文档地址&#xff1a;apache 官方 Dubbo 文档 其页面内容如下&#xff1a;&#xff08;我是用 chrome 直接右键翻译的&#xff0c;原文档是英文的&#xff09;

制动踏板是什么?

制动踏板就是脚刹&#xff08;行车制动器&#xff09;的踏板&#xff0c;使运行中的机车、车辆及其他运输工具或机械等停止或减低速度的动作。制动的一般原理是在机器的高速轴上固定一个轮或盘&#xff0c;在机座上安装与之相适应的闸瓦、带或盘&#xff0c;在外力作用下使之产…

CSS Framework 960 Grid System (收)

CSS框架 &#xff1a;960 Grid System 官网&#xff1a;http://960.gs/ 什么是框架&#xff1f;框架是一种你能够使用在你的web项目中概念上的结构。CSS框架一般是CSS文件的集合&#xff0c;包括基本风格的字体排版&#xff0c;表单样式&#xff0c;表格布局等等&#xff0c;比…

使用线程本地存储

线程本地存储&#xff08;TLS&#xff09;使同一进程的多个线程能够使用由TlsAlloc函数分配的索引来存储和检索线程本地的值。在此示例中&#xff0c;在进程启动时分配索引。当每个线程启动时&#xff0c;它会分配一个动态内存块&#xff0c;并使用TlsSetValue函数在TLS槽中存储…

发动机的工作原理,你知道吗?

http://auto.jxedt.com/info/5352.htm 发动机是汽车的动力装置&#xff0c;性能优劣直接影响到汽车性能&#xff0c;发动机的类型很多&#xff0c;结构各异&#xff0c;以适应不同车型的需要。按发动机使用燃料划分&#xff0c;可分成汽油发动机和柴油发动机等类别。按发动机汽…

官方文档: Dubbo 框架设计、模块说明、依赖关系

以下内容全文转自 apache 官方 dubbo文档&#xff1a;http://dubbo.apache.org/en-us/docs/dev/design.html 框架设计 图片描述&#xff1a; 浅蓝色背景的左侧区域显示服务用户界面&#xff0c;浅绿色背景的右侧区域显示服务提供者界面&#xff0c;中心区域显示两个侧面界面。…

那些花儿

今天上海下雨了&#xff0c;心绪也变得低落&#xff0c;突然很想念宿舍的姐妹。毕业后就自作聪明地和她们失去了联系&#xff0c;今天去QQ群遛了一圈。虹结婚了&#xff0c;敏还是活得那么潇洒&#xff0c;笑也在努力地生活... 人生啊&#xff01;总是在向前走&#xff0c;遇…

CreateRemoteThread函数

CreateRemoteThread函数 创建在另一个进程的虚拟地址空间中运行的线程。 使用CreateRemoteThreadEx函数创建在另一个进程的虚拟地址空间中运行的线程&#xff0c;并可选择指定扩展属性。 语法 HANDLE CreateRemoteThread(HANDLE hProcess,LPSECURITY_ATTRI…