*与**、函数嵌套、对象、作用域、闭包函数

 *、函数嵌套、对象、作用域、闭包函数

1.args(*)与kwargs(**) 在函数里面调用函数,用args和kwargs

def index(a,b,c):
    print(a,b,c)

def wrapper(*args,**kwargs):  # args=(1,2,3)    kwargs={}
    index(*args,**kwargs)  # index(*(1,2,3) ,**{})  # index(1,2,3)
 						
#index(b=2,c=3,a=1)   
wrapper(1,2,3)   相当于直接调用index  完整的传给index 但是需要形参全部对上
wrapper(b=2,c=3,a=1)  

2.函数嵌套 在调用一个函数的过程中,又调用了其他函数

2.1案例 四个数字求最大值
	def max2(x,y):
    if int(x)>int(y):
        return x
    else:
        return y
def max(x,y,k,z):
    res1=max2(x,y)
    res2=max2(res1,k)
    res3=max2(res2,z)
    print(res3)
max(5,6,10,8)
输出结果为 10
2.2函数的嵌套定义: 在函数内又定义了一个函数
     #定义在函数内部的内容有一个效果:函数外无法访问,只有在函数内才可以访问到
     案例:求圆的面积和周长  大方法里通过一个形参指定调用面积或者周长
     from math import pi 
def cirle(radius,xxx=0):
    def area(radius):
        result=pi * (radius**2)
        print('面积为:',result)
    def perimeter (radius):
        result=2*pi*radius
        print('周长为:',result)
    if xxx==0:
        area(radius)
    elif xxx==1:
        perimeter(radius)
    else:
        print("输入错误,请输入0或者1")

cirle(10,1)
    输出结果为:周长为: 62.83185307179586

3.函数对象

def foo():  # foo->函数的内存地址   函数名存的都是地址
    print('from foo')
1、可以被赋值
y = x      #x的内存地址赋值给y
f = foo    #foo的内存地址赋值给f
2.可以当做参数传入
def f1(func):     #定义f1函数 形参为随意指定
	print('====>f1')
	func()           #调用输入的这个方法   方法不加括号是内存地址  加括号为调用方法
f1(foo)  # f1(函数的内存地址 = foo内存地址)
3.可以当做返回值
def f1(func):     #定义f1函数   
     return func   # 返回传进去的内存地址

f = f1(foo)       #调用f1方法吧foo内存地址赋值给f
print(f)          #输出的事foo内存地址
4.可以当做容器类型的元素 
x = 10   
l = [x,foo,foo()]   #先执行一遍foo()  
#print(l)           #x的值10,foo内存地址 ,  foo函数执行一遍

l[1]()            #执行foo函数地址 加()为方法
案例 做一个 登录login 注册register 转账transfer 提现withdraw等功能的交互式界面
#定义几个方法
def login ():
    print("我是登录功能".center(50,'$'))
def register ():
    print("我是注册功能".center(50,'$'))
def transfer ():
    print("我是转账功能".center(50,'$'))
def withdraw ():
    print('我是提现功能'.center(50,'$'))

#定义一个字典存方法对应的索引 显示的内容和内存地址
func_dic ={
    '1':['登录功能',login],
    '2':['注册功能',login],
    '3':['转账功能',login],
    '4':['提现功能',login]
}
#大体思路为 while true一直循环  先输出一个0退出,然后循环字典  把key和value的第一个元素打印出来  ,
#然后让用户选择并输入==0退出,if 判断输入的值在这个字典的key是否存在,存在则通过字典key找到value的第二个元素,是内存地址然后加一个()则为调用这个内存地址的函数,如果不存在则输入有误

while True:
    print('0 退出')
    for line in func_dic:
        print(line,func_dic[line][0])
    temp=input('请输入要选择的功能').strip()
    if temp=='0':
        break
    if temp in func_dic:
        func_dic[temp][1]()
    else:
        print('你输入的有误,请从新输入')

4.名称空间和作用域

#名称空间Namespace:存放名字与内存地址绑定关系的地方
 #-内置名称空间:存放python解释器自带的名字
    比如 len  print 
 #-全局名称空间: 存放的是顶级的名字,如下x、z、f1、xxx都是
x = 100    # 个人了觉得除了局部空间和局部空间的上一层:外层函数Enclosing剩下都是全局名称空间 
def f1():       #f1是
    y = 200    #y不是

if 10 > 3:   
    z = 300   #z是 没在函数里面

    if True:
        xxx = 400   #xxx也是只是被if包裹了
 #-局部名称空间:存放的是函数内定义的名字
def f1():    
    y = 200 
 #-结论1:	LEGB  局部Local-》外层函数Enclosing-》全局Global-》内置Builtin
#重要结论2:名称空间的嵌套关系是在函数定义阶段、扫描语法时就确定好的,与调用位置无关
	调用方法时一步一步看 ,看在哪调用,正常先在局部找,没有在外层,然后全局,然后内置
    加载到内存时 先内置  在全局   ,外层 局部 和上面的相反      全局和内置随着程序结束而结束    局部随着调用结束就结束
# 全局作用域:全局存活,全局有效
#           内置名字空间、全局名称空间

# 局部作用域:临时存活,局部有效
#           局部名称空间 

 =============global关键字    把变量变成全局变量
    变量定义为全局的
l = []
x = 100
def foo():
    l.append(333)

    global x          #定义x为全局的
    x = 200           #修改

foo()

print(l)
print(x)
输出结果[333]       200

=============nonlocal关键字 用来在函数或其他作用域中使用外层(非全局)变量。
x = 111
def f1():
     x = 222
    def f2():
        nonlocal x          #调用外层函数用的是外层的
        x = 333

    f2()
    print('==========>f1肚子里的x: ',x)

 f1()

 print(x)
输出结果==========>f1肚子里的x:  222
111

5.闭合函数

闭函数:定义在函数内部的函数
def outter():
    def wrapper():
        print('====>wrapper')

包函数: 内部函数引用了一个来自于外层函数的变量
def outter():
    x = 111
    def wrapper():
        print('====>wrapper',x)

posted @ 2021-08-09 19:20  迪迦张  阅读(27)  评论(0编辑  收藏  举报