Python函数2,,一、命名空间:什么是


一、命名空间:

什么是命名空间:

  --> Python代码在执行的过程中从上到下顺序执行,

  -->从python解释器开始执行之后,就在内存中开辟了一个空间。

  -->每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。

  --> 但是,当遇到函数的时候,Python解释器只是将函数名称读入内存,并且知道这个函数已经存在了,此时,函数内部的变量和逻辑关系解释器根本就不关心,并没有执行函数内部的代码

  --> 等到执行函数的调用的时候,Python解释器才会在内存中再开辟一块儿空间,来存储函数里面的代码内容,这个时候,才会关注函数内部有哪些变量。函数内部的变量存储在新开辟的空间中,只能供函数内部使用,等函数执行完毕,这块儿内存空间中所有内容都会被清空。

  -->我们给这个“存放名字与值的关系”的空间起了一个名字——叫做命名空间

命名空间分为三种:全局命名空间,局部命名空间,内置命名空间。

1.首先先说下内置命名空间:里面包含了Python解释器为我们提供的一些名字。比如:input,print,list,tuple等等。我们直接拿过来用就可以。

2.全局命名空间:代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间。

3.局部命名空间:在函数的运行中开辟的临时的空间叫做局部命名空间。

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

关于作用域:作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

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

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

关于global关键字

来看一段代码:

a = 1def func():    a = 20print(a)func()print(a)

上面的代码打印结果

11

第一个 print(a)在调用函数之前打印 a 的值,打印 1 ,后面调用函数,在函数内部,明明已经修改了 a的值,后面打印 还是打印 1 。其实,第一个 a = 1.这个a 是全局命名空间。在函数内部 a = 20 ,这个a是局部命名空间,如果想在函数内部,对全局变量的值做修改,可以使用关键字 global

a = 1def func():    global a    a = 20print(a)func()print(a)

这次的打印结果

120

二、关于函数的探讨

先看一段代码:

def func(): # 定义一个函数    passf = func # 将函数名称赋值给一个变量print(func) # 打印函数名称print(f) # 打印变量 f

执行结果

<function func at 0x000000000050C1E0> # 翻译结果:0x000000000050c1e0处的函数func<function func at 0x000000000050C1E0>

从结果中可以看出:函数名称实际上存放的是这个函数的一个内存地址,另外,函数名也可以赋值给一个变量,其实函数名也是一个变量

既然函数名本质上其实就是一个变量,那么,函数名也就可以作为容器中的一个元素。如:

def func1():    passdef func2():    passdef func3():    passlist_func = [func1,func2,func3]for l_func in list_func:    print(l_func)

打印结果

<function func1 at 0x00000000003DC1E0><function func2 at 0x0000000002718510><function func3 at 0x0000000002718598>

也可以当做函数的参数以及返回值

def outer():    name = ‘jack‘    def inner():        print(name)    return innerouter()

三、闭包:内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

来看一段代码

def outer(x):    def inner(y):        return x + y    print(inner.__closure__)  # 使用__closure__ 判断是否为闭包,如果输出包含cell 则是闭包。如果输出为None 则不是闭包    return innerf = outer(9)print(type(f)) # 打印f的类型print(f.__name__) # 输出 f 的名字

输出结果

(<cell at 0x00000000021DB858: int object at 0x000007FEDFC5D520>,)<class ‘function‘>inner

结合这段简单的代码和定义来说明闭包:
如果在一个内部函数里:inner(y)就是这个内部函数,对外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量(x在外部作用域outer里面,但是不是全局作用域),name这个内部函数就是一个闭包

使用闭包的注意事项:

在闭包中,是不能修改外部作用域的变量的值

def outer():    a = 0    def inner():        a = 1        print(a)    print(a)    inner()    return innerouter()

打印结果

01

另外需要注意的一点是:闭包不要引用任何的循环变量,或者后续会发生变化的变量

Python函数2

评论关闭