zoukankan      html  css  js  c++  java
  • 函数进阶

    一、名称空间

    1、什么是名称空间

    名称到对象的映射。命名空间是一个字典的实现,键为变量名,值是变量对应的值,各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响

    通俗讲:名称空间就是存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢,名称空间正是存放名字x与1绑定关系的地方)

    2、名称空间分类

    全局名称空间(global):每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块,模块级的变量与常量

    局部命名空间(local):每个函数所拥有的命名空间,记录了函数中定义的所有变量,包括函数的入参、内部定义的局部变量

    内置命名空间(built-in):任何模块均可以访问,放着内置的函数和异常(比如:input,print,str,list,tuple)

    3、名称空间的加载顺序

    内置名称空间(程序运行前加载)-->全局命名空间(程序运行中:从上到下加载)-->局部命名空间(程序运行中:调用时才加载)

    4、名称空间的取值顺序

    在局部调用:局部命名空间-->全局命名空间-->内置命名空间

    在全局调用:全局命名空间-->内置命名空间

    综上所述,在寻找变量时,从小范围,一层一层到大范围去找寻

    二、作用域

    1、什么是作用域

    作用域是针对变量而言,指申明的变量在程序里的可应用范围,或者称为变量的可见性

    2、作用域分类

    按照生效范围可以分为全局作用域和局部作用域

    全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用,全局有效

    局部作用域:局部名称空间,只能在局部范围内生效

    3、查看作用域的值

    locals()和globals(),他们提供了基于字典的访问局部和全局变量的方式

    locals():函数会以字典类型返回当前位置的全部局部变量

    globals():函数会以字典类型返回当前位置的全部全局变量

    4、关键字(global与nonlocal)

    global的作用:

      声明一个全局变量

      在局部作用域想要对全局作用域的全局变量进行修改时,需要用到global(限于字符串,数字)

    def func():
        global a
        a=2
        print(a)
    
    func()
    print(a)
    """
    2
    2
    """

    注意:对可变数据类型(list,dict,set)可以直接引用,不用通过global

    li=[1,2,3]
    dic={'a':'b'}
    def change():
        li.append('a')
        dic['q']='g'
        print(dic)
        print(li)
    change()
    print(li)
    print(dic)
    """
    {'a': 'b', 'q': 'g'}
    [1, 2, 3, 'a']
    [1, 2, 3, 'a']
    {'a': 'b', 'q': 'g'}
    """

    nonlocal的作用

      不能修改全局变量

      在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从哪层及以下此变量全部发生改变

    def add_b():
        b=42
        def do_global():
            b=10
            print(b)
            def dd_nonlocal():
                nonlocal b
                b+=20
                print(b)
            dd_nonlocal()
            print(b)
        do_global()
        print(b)
    
    add_b()
    """
    10
    30
    30
    42
    """

    三、函数名的本质

    函数名本质上就是函数的内存地址

    1、可以被当做值或变量引用

    def func():
        pass
    print(func)
    f=func  #将其传给变量f
    print(f)
    """
    <function func at 0x00000000005C3E18>
    <function func at 0x00000000005C3E18>
    """

    2、函数可以被当做容器类型的元素存储

    def func1():
        print('func1')
    def func2():
        print('func2')
    def func3():
        print('func3')
    lis=[func1,func2,func3]
    lis[0]()
    lis[1]()
    lis[2]()
    """
    func1
    func2
    func3
    """

    3、可以当做函数的参数和返回值

    def func1():
        print('func1')
    def func(argv):
        argv()
        return argv #func1作为返回值

    f=func(func1) #func1作为参数 f() """ func1 func1 """

    四、闭包

    在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包(即:内层函数,对外层函数(非全局)的变量的引用)

    example(例子):

    def func():
        name='eva'
        def inner():
            print(name)
        return inner
    
    f=func()
    f() #eva

    1、检测闭包函数的公共属性:closure

    如果里层的函数调用__closure__方法输出是一个cell对象,则证明是闭包

    def wrapper():
        name='是闭包'
        def inner():
            print(name)#调用外层函数的变量
        inner()
        print(inner.__closure__)
    wrapper()
    """
    是闭包
    (<cell at 0x0000000001C40C48: str object at 0x00000000028657B0>,)
    """

    2、带有参数的闭包函数

    def wrapper(a):#a是外部传入的参数
        b=10
        def inner(a):
            print(a+b)
            return a+b
        inner(a)
    wrapper(10)#20
  • 相关阅读:
    Minimum Sum of Array(map迭代器)
    stl库中的map (反向迭代器)以及例题
    stl库中反转的函数
    如何使用java中的对象
    java中的成员变量和局部变量
    java中的构造方法
    static使用之静态变量
    什么是类和对象
    如何定义java中的类
    css让图片作为按钮的背景并且大小合适
  • 原文地址:https://www.cnblogs.com/z-x-y/p/9177617.html
Copyright © 2011-2022 走看看