• 函数的名称空间和作用域


    一、函数是第一类对象

    1.函数:

    -定义:
    

    ​ 函数的名字就是函数的对象,函数名指向的函数的内存地址。

    ​ -有什么用?

    ​ -可以被引用

    ​ -可以被当作参数传入

    ​ -可以当作函数的返回值

    ​ -可以当作参数传入容器中

    函数对象的应用:

    	可以优雅的的取代if的分支
    
    def index():
        '''
        无参函数
        '''
         print('from index')
    
    print(index)  ##打印的是变量名的内存地址
    >>>>>>
    <function index at 0x0000015038D81EA0>
    
    
    
    def index(l1):
        '''
        
       求列表的长度 
        '''
        print(len(l1))
    
    l1 = [1,2,4,'afew']
    index(l1)   ######调用函数 打印上面的print 的值 4
    print(index(l1))####有index()都是要调用函数,打印上面的print   print(index())打印返                           回值,没有return 则返回none
    >>>>>>>
    4
    4
    None
    

    1.函数名是可以被引用的

    name = 'tank'
    dsb = name
    与上面的是类似的用法
    f=def index():
        '''
        可以被引用
        '''
        print('from the index')
    a = index
    a()
    >>>>>>
    from the index
    

    2.函数名可以当作参数传递

    def foo(x,y,func):
        '''
    
        函数的名可以当作参数传递
        '''
        print(x,y)
        func()
    def bar():
        print('from the bar')
    foo(1,2,bar)
    >>>>>>
    1 2 
    from the bar
    

    3.函数名可以当作返回值使用,

    传参的时候没有特殊要求,一定不要加括号,加括号当场执行

    def index():
        '''
        
        函数名可以当作返回值用 
        '''
        print('from the index')
    def func(a):
        return(a)
    b = func(index)  ##### index  === return 中 的a    下main就是 index()
    b()
    
    >>>>>>>
    from the index
    

    4、函数名可以被当做容器类型的元素

    def func():
        '''
        函数名可以作为容器类型的元素
        '''
        print('from ')
    
    l1 = [1,2,func,func()]#####正常的python解释器的走向 从上到下 从左到右 定格写的                                        (1,2,func())   也可以调用func()的函数
    f = l1[2]
    print(f)
    >>>>>>>
    from   
    <function func at 0x0000016D90FC1EA0> ####func的内存地址
    
    

    购物车的一个程序

    def register():
        print('register')
    def login():
        print('login')
    def shopping():
        print('shopping')
    def pay():
        print('pay')
    func_dic = {
        '1' : register,
        '2' : login,
        '3' : shopping,
        '4' : pay
    }
    def main():
        while True:
            print('''
            1、注册
            2、登录
            3、购物
            4、付款
            ''')
            choice = input('请输入对应的编号: ').strip()
            if choice == '5':
                break
            elif choice not in func_dic:
                continue
            else:
                func_dic[choice]()
    
    
    main()
    
    

    二、函数的嵌套

    -函数的嵌套的定义:

    ​ -让内层函数封闭起来,不让外部直接调用。

    -作用

    ​ -将功能并且小的功能,在函数内部调用,解决代码结构清晰问题。

    def  index():
        ''''
        函数的嵌套
        '''
        print('from the world')
    def func():
        index()
        print('from the world')
    func()
    >>>>>>
    from the world
    from the world
    
    
    举例 2
    
    def index(x, y):
        '''
    
       函数的嵌套
        '''
        if x > y:
            return x
        else:
            return y
    print(index(index(index(1,2),3),6))
    print(index(1,4))
    >>>>>>>
    6
    4
    举例3
    def index(x, y):
        '''
    
       函数的嵌套
        '''
        if x > y:
            return x
        else:
            return y
    def index_2(x,y,z,a):
        result = index(x,y)
        result = index(result, z)
        result = index(result,a)
        return result
    print(index_2(1,2000,3,1000))
    >>>>>>
    2000
    举例4
    def index():
        '''
        
       函数的嵌套
        '''
        def home():
            print('well')
        home()
    index()
    >>>>>>
    well
    

    三、名称空间

    什么是名称空间?
        存放名字的空间   名称空间是一个在内存种的空间
        如果你想访问一个变量值,必须先访问对应的名称空间,拿到名字和对应的内存地址的绑定关系
        名称空间的分类:
        1、内置名称空间:
            python提前给你的定义完的名字,就是存在内置名称空间
      
            print(input)
            >>>>>>
            <built-in function input>
        2、全局名称空间
            存放于文件级别的名字,就是全局名称空间
            if while for 内部定义的名字执行之后都存放于全局名称空间
            x = 1
            print(x)
        3、局部名称空间
            函数内部定义的所有名字都是存放与当前函数的内置名称空间
            
            生命周期:
        1、内置名称空间
            在python解释器启动的时候生效,关闭解释器的时候销毁
        2、全局名称空间
            当你启动当前这个py文件的时候生效,当前页面代码执行结束之后销毁,关闭python解释器时,彻底 销毁。
            x = 1   ####这个变量就是存放于全局名称空间
            def index():
                '''
                取x的值
                '''
                print(x)
            index()
                >>>>>>>>>>
                   1
            Process finished with exit code 1 ####这个代表的是代码执行结束
        3、局部名称空间
            当你调用当前函数时生效,临时存活,函数调用结束后销毁。
            def index():
                x = 1     ###变量存放于局部的名称空间。
                print(x)
            index()
            >>>>>>
            1
        
    
    
    

    下图是名称空间的图片

    ![img](file:///C:Users86187DocumentsTencent Files1341212001ImageGroup3K0L@[`%FVSWG}UW]6YQJLV.jpg)

    四、名称空间的查找顺序

    def index():#####index是全局变量名称空间
        '''
       print的值
        '''
        x = 1     ######x 是局部名称变量空间
        return x
    print(index)#####没有执行函数,但是内存地址在定义函数的时候已经确定了,所以可以打印的出来
    
    def foo():
        print(index) ######执行函数  打印的是index的内存地址
    foo()
    >>>>>>>>
    <function index at 0x0000029F5B0A1EA0>
    <function index at 0x0000029F5B0A1EA0>
    
    
    
    ######名称空间的查找顺序:######
        -加载顺序:内置--->全局---->局部
        -查找顺序:局部--->全局---->内置
    # 函数内部使用的名字,在义阶段已经规定死了,与你的调用位置无关
    如下图的是print(x)是函数内部使用的名字
    
    x = 1
    def index():
        '''
    
        查看局部变量
        '''
        print(x)
    def wrapper():###这个是个局部的变量 不能赋给到上面的一层 
        x = 2
        index()
    wrapper()
    >>>>>
    1
    下面的例子
    x = 1
    def index():
        '''
    
        查看局部变量
        '''
        x = 3    #####局部从新有了名称空间,先用局部的 ,局部没有的话,才会去找全局的,wrapper属于是内层的嵌套,更低一级,也是不能操作的
        print(x)
    def wrapper():
        x = 2
        index()
    wrapper()
    >>>>>
    3
    
    

    1111

    x = 1
    def inner():
        x = 2
        def wrapper():
            print(x)####上面一层的x =2是最后赋值的
        wrapper()
    x = 111
    inner()
    >>>>>>>
    2
    下面的一个例子
    x = 1
    def inner():
        # x = 2
        def wrapper():
            print(x)
        wrapper()
    x = 111
    inner()
    >>>>>>>
    111
    

    全局变量名称空间的一个例子

    x = 1
    def index():
         x = 2
    
    print(x)
    >>>>>>>
    1     ######  这个的只是定义函数阶段,全局变量找值,如果没有就报错 不会去找局部变量的名称空间
    
    在定义阶段的,提前给形参复制的操作就是默认值参数
    
    x= 1
    def index(arg = x):######arg 已经给赋值给1  下面的不会动
        '''
        看全局名空和局部明空的区别
        '''
        print(x)
        print(arg)#####只有掉用函数的时候,index(有值传入才可以把默认的arg = x,进行修改)
    x = 2    #####     x被从新赋值给2
    index()
    >>>>>>>
    2
    1
    
    另外一个例子
    x = 1
    def index():
        '''
    
        全局名称空间
        '''
        def wrapper(): 
            print(x)
        return wrapper#####return 在index函数的下方,所有返回的wrapper给了f,f =wrapper ,wrapper()执行wrapper的函数
    f = index()
    f()
    >>>>>>
    1
    
    
    

    五、作用域的分类

    作用域:
    名称空间的作用范围
    
    作用域的分类:
        1、全局作用域
            -全局可以调用的名字就存在于全局作用域
            -只要程序一直执行,永久存活,若程序结束,则销毁
             内置名称空间+全局名称空间
        2、局部作用域
            局部可以调用的名字就存放与局部作用域
              -局部的名称空间+局部的局部名称空间、
              -只要程序一直执行,调用函数时存活,结束时销毁。
            
            局部名称空间
    
    global:声明全局变量(***)
    nonlocal:在局部名称空间声明局部变量,在局部修改上层函数的变量(*)
    
    只有可变类型可以在局部修改外部变量的值 (*****)
    
    全局变量的举例
    def index():
        # global x
        x = 2   ######x = 2 是局部变量名空  不能被全局的x(print(x))的调用
        print()
    index()
    print(x)
    >>>>>>>>
      print(x)   
    NameError: name 'x' is not defined
        
        修正后
    def index():
        global x   ######声明了x为全局的变量名称空间
        x = 2
        print()
    index()
    print(x)
    >>>>>>>
    2
    
    nonlocal 
    
    def index():
        '''
        
        nonlocal  ####在局部的名称空间声明局部变量
        '''
        x = 1
        def func():
            nonlocal x
            x = 2
        func()
        print(x)###如果没有nonlocal  打印出来的结果是1
    index()
    >>>>>>>
    2
    
    
    x = 1
    def func():
    
        def wrapper():
            global x    ####这个声明了修改x = 1 全局变量  所以打印结果x = 2
            x = 2
        wrapper()
        print(x)
    func()
    >>>>>>>>>
    2
    
    
    ######只有可变类型可以在局部修改外部变量的值 (*****)
    
    l1 = []
    def index(a):
        '''
        
        可变的列表比较特殊 
        '''
        l1.append(a)
        #print(l1)
    index(1)
    print(l1)
    >>>>>>>
    [1]
    
    
    局部变量的修改无法影响上层,上上层
    
    def index():
        x = 1
    
        def index2():
            nonlocal x
            x = 2
    
        index2()
        print(x)####如果没有nonlocal 打印的结果就是1
    
    
    index()
    >>>>>>>>
    2
    
    局部变量的修改无法影响上层,上上层
    
    
    x = 111
    def index():
        x = 1
    
        def func2():
            x = 2
    
            def func():
                nonlocal x
                x = 3
    
            func()
            print(x)###因为在局部名称空间声明了局部变量,在局部修改上层函数的变量
    
        func2()
        print(x)
    
    
    index()
    print(x)
    >>>>>>
    3
    1
    1111
    
    
  • 相关阅读:
    利用clear清除浮动的一些问题
    配置SpringBoot方便的切换jar和war
    java并发实战:连接池实现
    canvas绘制圆角头像
    对象的合并及拷贝
    JS数组去重
    浏览器端用JS实现创建和下载图片
    超过固定宽度(或行数)显示...(或省略)
    ssh实现免密登录
    Mac 日常使用问题收集
  • 原文地址:https://www.cnblogs.com/bs2019/p/11851761.html
Copyright © 2020-2023  润新知