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

    函数的命名空间

    从python解释器开始执行之后,就在内存中开辟了一个空间,每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。

    但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。

    等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。

    函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

    1. 全局命名空间:是在程序从上到下被执行的过程中依次加载进内存的,放置了我们设置的所有变量名

    2. 局部命名空间:函数内部定义的名字,调用函数的时候参会产生命名空间,函数执行结束命名空间消失

    3. 内置命名空间:python解释器启动即可使用,内置的名字在启动解释器的时候被加载进内存中

    a = 1        #属于全局命名空间
    def func():
        b = 2     # 属于局部命名空间
        print('abc') # 属于内置命名空间
        
    func()
    print(a)

    作用域

        全局作用域:作用在全局,内置和全局命名空间中的名字属于全局作用域

        局部作用域:函数内,作用在局部

    local, locals, globals 关键字

    local 可在局部调用全局变量,慎用

    a = 1
    def func():
        global a
        a += 1
    func()
    print(a)
    2

    locals 查看局部所有变量,globals可查看全局变量

    a = 1
    def func():
        b = 2
        global a
        a += 1
        print(a)
        print(locals())
        print(globals())
    func()
    
    2
    {'b': 2}
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001A02E31A518>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/python学习/day10/复习.py', '__cached__': None, 'a': 2, 'func': <function func at 0x000001A02E3FB0D0>}

    函数的嵌套和调用

    函数的额嵌套,函数内嵌套函数。

    nonlocal函数调用上一层函数变量,若没有则上上一层函数

    a = 1
    def outer():
        a = 2
        def inner():
         # a = 4 * 错误的位置
            nonlocal a   # 若本层函数有变量,则用本层变量,本层没有调用上一层
            a = 4      # 相同名字的变量 a 只能定义在nonlocal下面,不能定义在上面
            a += 1
            print(a)
        inner()
    outer()
    5
    
    def outer():
        a = 2
        def inner():
            nonlocal a
            a += 1
            print(a)
        inner()
    outer()
    3

    函数名的本质

    函数名就是内存地址
    def func1():
        print(123)
    func2 = func1     # 1.函数名可以赋值func2()
    l = [func1,func2] # 2.函数名可以作为容器类型的元素
    print(l)
    for i in l:
        i()  # 内存地址加括号即可执行函数,
    
    def func():
        print(123)
    
    def wahaha(f):
        f()
        return f
    
    wahaha(func) # 3.函数名可以作为函数的参数
    qqxing = wahaha()
    qqxing()     # 4.函数名可以作为返回值

    闭包

    # 1.嵌套函数
    # 2.内部函数调用外部函数的变量
    
    最简单闭包:
    def outer(): a = 1 def inner(): print(a)
    闭包调用举例:
    def outer(): a = "内部变量a" def inner(): print(a) return inner  返回函数内存地址给outer() inn = outer()   inn()
    # 通过闭包可以将函数内部的函数,变量,调用给外部函数。 # 如果反复调用函数。避免 变量 在函数内的反复生存和死亡

     学到看到这里我是有点疑惑,闭包中似乎不需要nonlocal就可以调用上一层函数啊,还要nonlocal有啥用啊,

    def outer():
        a = 1
        def inner():
            nonlocal a  
            a += 1    
            print(a)
        inner()
    outer()
    
    def outer():
        a = 1
        def inner():
            # nonlocal a    如果对上层变量进行修改,似乎必须地用nonlocal调用上层函数。如果不修改,则可以直接调用。
            # a += 1
            print(a)
        inner()
    outer()
  • 相关阅读:
    关于深浅克隆
    忙话codesmith
    SynchronizedDictionary线程安全的泛型版本
    自制定长的Queue
    白忙活
    发现一个不错的技术社区(水木清华)
    自已实现线程池
    Berkeley DB .net 进行添加和更新操作
    关于ThreadPool.RegisterWaitForSingleObject和WaitHandle的应用介绍
    1100内产生3个不重复的随机数
  • 原文地址:https://www.cnblogs.com/jiuyachun/p/10405201.html
Copyright © 2011-2022 走看看