python基础三_02_函数的作用域

python基础三_02_函数的作用域

导读:
本文主要记录自己学习python3基础中函数的作用域(全局变量与局部变量等)要点知识和例子;仅供自己梳理。搞清楚函数的作用域很关键,这是理解闭包,装饰器等的前提。

一、引子

def func():
    x = 1
    print(x)

func()
print(x)

python基础三_02_函数的作用域_第1张图片

1.分析:如上,为何在函数外部打印x的值没有结果呢?

这是因为x是func函数内部的变量。
随着func的生命周期当函数调用完成,没有变量指向1的内存地址后,python的垃圾回收机制就会回收1的内存
所以就出现了:NameError: name 'x' is not defined,这个很容易理解
x = 6
def func():
    x = 1
    print(x)

func()
print(x)

在这里插入图片描述

2.分析:现在为何可以在func函数外部打印x的值呢?

这是因为我们定义了全局变量,x = 6

二、函数的作用域

1.变量起作用的范围

  • L local局部作用域,本地作用域
  • E enclosing嵌套作用域
  • G global全局作用域
  • B built-in内建作用域
for,if,while返些流程控制不会形成自己的作用域
import sys
# 得到所有该模块的方法 内建作用域
print(dir(sys))
# 全局
name = 'while'
def outer():
    name = 'for'# 嵌套作用域
    def inner():
        # 本地作用域
        name = 'json'
        age = 18
        print(name)
        print(age)
    inner()

outer()
初学者可能看不太懂上面的程序,我们来分析一下:
name = 'while'
def outer():
    name = 'for'
    def inner():
        name = 'json'
        age = 18
        print(name)
        print(age)
        
outer()

2.分析:执行后为什么啥结果都没有呢?

这是因为我们只调用了outer函数,但真正想调用的inner函数没有调用。
有的人可能一眼就看出来了,但是对初学者来说可能有点勉强。
好比下面的程序,你觉得它会有输出内容吗?
name = 'for'
def inner():
    name = 'json'
    age = 18
    print(name)
    print(age)
	这个程序当然不会输出任何东西,原因是它只定义了name和inner,但是并没有调用。
	仔细看它是不是就是outer函数里面的东西呢?
	我们只要调用一下inner函数就可以了。
	name = 'for'
	def inner():
	    name = 'json'
	    age = 18
	    print(name)
	    print(age)
	inner()

3.变量起作用的范围

现在我们肯定都能看懂这个程序
# 全局作用域,全局变量
name = 'while'
# 定义外层函数
def outer():
    # 嵌套作用域,嵌套变量
    name = 'for'
    # 定义内嵌函数
    def inner():
        # 本地作用域,局部变量
        name = 'json'
        age = 18
        print(name)
        print(age)
    inner()
        
outer()

在这里插入图片描述

如果本地作用域没有定义name变量呢?
# 全局作用域,全局变量
name = 'while'
# 定义外层函数
def outer():
    # 嵌套作用域,嵌套变量
    name = 'for'
    # 定义内嵌函数
    def inner():
        # 本地作用域,局部变量
        # name = 'json'
        age = 18
        print(name)
        print(age)
    inner()
        
outer()

在这里插入图片描述

 分析:因为本地作用域中没有定义name,所以程序执行时会向上一层找,也就是嵌套作用域:name = 'for'
如果嵌套作用域也没有定义name变量呢?
# 全局作用域,全局变量
name = 'while'
def outer():
    # 嵌套作用域,嵌套变量
    # name = 'for'
    def inner():
        # 本地作用域,局部变量
        # name = 'json'
        age = 18
        print(name)
        print(age)
    inner()
        
outer()

在这里插入图片描述

分析:相应的如果嵌套作用域还没有定义name变量,那么就再向上一层,直到全局作用域,name = 'while'
当然,如果全局作用域还没有变量的定义,就会报错

3.同样,那我们现在能访问(即:打印)变量age吗?

name = 'while'

def outer():
    # 嵌套作用域,嵌套变量
    # name = 'for'
    def inner():
        # 本地作用域,局部变量
        # name = 'json'
        age = 18
        print(name)
        print(age)
    inner()
        
outer()
#
print(age)

python基础三_02_函数的作用域_第2张图片

分析:
当然不能,因为age是inner函数的变量,是局部变量,它和inner函数一样有生命周期和作用范围,它不在全局。
函数内部定义的数据函数外部无法访问,即函数具有封闭性,函数可以封装代码即具有包裹性,所以函数可以构成闭包。闭包我们下次聊。

三、global

什么叫局部变量,全局变量?

局部变量是指在程序中只在特定过程戒函数中可以访问的变量,函数内部定义的变量。
如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,返样的变量就是全局变量
 总结:不同的函数,可以定义相同的名字的局部变量,但是各用各的不会产生影响。
 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用。

1.修改全局变量

现在打印出来的肯定是json,我现在想在本地作用域中,越级直接修改你的全局变量,怎么搞?关键字global可以实现
name = 'while'
print(name)

def outer():
    # 嵌套作用域,嵌套变量
    name = 'for'
    def inner():
        # 本地作用域,局部变量
        # global声明一般在最前面,修改全局变量name
        global name
        name = 'json'
        age = 18
        print(name)
        print(age)
    inner()
        
outer()
print(name)  #这里本应该打印出的是while

python基础三_02_函数的作用域_第3张图片

2.那如果我只想修改嵌套变量呢?

nonlocal声明修改嵌套变量name
name = 'while'

def outer():
    # 嵌套作用域,嵌套变量
    name = 'for'
    print(name)
    def inner():
        # 本地作用域,局部变量
        # nonlocal声明修改嵌套变量name
        nonlocal name
        name = 'json'
        age = 18
        print(name)
        print(age)
    inner()
    print(name)
    
outer()

在这里插入图片描述

3.修改可变数据类型没有必要声明global

在上面的例子中,字符串属于不可修改的所以需要用global声明。但如果是可修改的数据类型,如:list,set,dict在修改时没有必要声明global。
c = [1,2,3]
d = {}
e = set()

def test():
    c.append('5')
    d.update({'name':'ydxq'})
    e.add(1)

test()
print(c,d,e)

在这里插入图片描述

用不用global声明,本质上是python变量内存的指针是否变动。可修改的数据类型在改变时指针指向不变,所以可以不用声明global等。
但不可修改的数据类型,只能通过重新指向一个内存地址来改变其值,所以需要global声明。

四、参考链接

Python 作用域和命名空间

Python中的局部变量和全局变量有哪些规则?

你可能感兴趣的:(python基础,python)