python之路 函数进阶

(一)python中函数运行的过程

python解释器开始执行之后,就在内存中开辟了一块内存空间。每当遇到一个变量的时候,就把变量名和变量值之间的对应关系记录下来。但是当遇到函数的时候解释器只是象征性的将函数名读入到存,表示知道这个函数存在了,对于函数内部的变量和逻辑解释器根本不关心。等到函数调用的时候,python解释器会再开辟一块空间来存储这个函数里的内容,这个时候才开始关注函数里面有哪些变量,而函数中的变量会存储在新开辟的内存空间中,函数中的变量只能在函数内部使用,并且会随着函数的执行完毕,这块内存中的所有内容也会被清空。我们给这个“存放名字和值得关系”的空间起了一个名字--------叫做命名空间。

(二)命名空间

首先,命名空间的本质就是存放名字与值的绑定关系

命名空间一共分为三种

内置命名空间:python解释器运行开始,就已经创建,内置命名空间存放了很多python为我们提供的方法

全局命名空间:代码运行开始,创建的存储“变量与值得关系”的空间叫全局命名空间

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

三种命名空间的加载与取值顺序

加载顺序:   内置命名空间-----》全局命名空间-------》局部命名空间

取值顺序:局部命名空间------》全局命名空间------》内置命名空间

(三)作用域

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

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

局部作用域包含局部名称空间,只能在局部生效。

globals 和  locals 方法

#在全局调用
print(globals())
print(locals())
#在局部调用globals和locals
def func():
    a = 12
    b = 20
    print(locals())
    print(globals())

func()

global 关键字

#global关键字的作用是声明变量的作用域
a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)

global关键字的作用是声明变量的作用域

(四)函数的嵌套 

#函数的嵌套
def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()

这里稍微补充三元运算

m  = x if x>y else y

如果x>y返回x,否则返回y。

nonlocal关键字

nonlocal是用来修改嵌套作用域中的变量,类似于global一样,只需要在嵌套函数中声明变量名即可,但是这个变量名是必须已经存在的,并且内部函数声明nonlocal变量之前不能再出现同名变量,否则就会报错,如果要修改的变量在作用域中找不到,那么不会继续到全局或内置作用域中查找。注意:内部函数只能在上一层函数中生效

def f1():
    a = 1
    def f2():
        nonlocal a
        a = 2
    f2()
    print('a in f1 : ',a)

f1()

(五)闭包函数

def func():
    name = 'eva'
    def inner():
        print(name)

在函数内部定义的函数称为内部函数

闭包函数:

内部函数包含对外部作用域而非全局作用域变量的引用,该内部函数称为闭包函数。由于作用域的关系,在函数外部是不能调用函数内部的函数的,这个时候需要将函数名return,这是闭包函数的常用方法。

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

f = func()
f()

判断是否是闭包函数的方法—closure—

#输出的__closure__有cell元素 :是闭包函数
def func():
    name = 'eva'
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f = func()
f()

#输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f2 = func2()
f2()
View Code

闭包函数获取网路应用

from urllib.request import urlopen

def index():
    url = "http://www.baidu.com"
    def get():
        return urlopen(url).read()
    return get

xiaohua = index()
content = xiaohua()
print(content)

闭包函数获取网络应用

(六)函数名的本质:(相当于普通变量的作用)

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

1,函数名可以被引用

2,函数名可以被当做容器类型的元素。

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

小结:三种命名空间:内置,全局和局部。函数嵌套:定义在函数内部的函数无法再全局被调用。函数名的本质相当于变量,保存了函数的内存地址。闭包函数:内部函数包含对外部作用域而非全局作用域变量的引用,称为闭包函数。

原文地址:https://www.cnblogs.com/shengzhongqiu/p/7242617.html