python函数作用域_python函数作用域(全局变量与局部变量、闭包)

作用域

变量到底是什么呢?可将其视为指向值的名称。因此,执行赋值语句x = 1后,名称x指向值1。这几乎与使用字典时一样(字典中的键指向值),只是你使用的是“看不见”的字典。实际上,这种解释已经离真相不远。有一个名为vars的内置函数,它返回这个不可见的字典:

>>> x = 1

>>> scope = vars()

>>> scope['x']

1

>>> scope['x'] += 1

>>> x

2

一般而言,不应修改vars返回的字典,因为根据Python官方文档的说法,这样做的结果是不确定的。换而言之,可能得不到你想要的结果。

这种“看不见的字典”称为命名空间或作用域。那么有多少个命名空间呢?除全局作用域外,每个函数调用都将创建一个。

>>> def foo(): x = 42

...

>>> x = 1

>>> foo()

>>> x

1

在这里,函数foo修改(重新关联)了变量x,但当你最终查看时,它根本没变。这是因为调用foo时创建了一个新的命名空间,供foo中的代码块使用。赋值语句x = 42是在这个内部作用域(局部命名空间)中执行的,不影响外部(全局)作用域内的x。在函数内使用的变量称为局部变量(与之相对的是全局变量)。参数类似于局部变量,因此参数与全局变量同名不会有任何问题。

>>> def output(x): print(x) g

...

>>> x = 1

>>> y = 2

>>> output(y)

2

到目前为止一切顺利。但如果要在函数中访问全局变量呢?如果只是想读取这种变量的值(不重新关联它),通常不会有任何问题。

>>> def combine(parameter): print(parameter + external)

...

>>> external = 'berry'

>>> combine('Shrub')

Shrubberry

像这样访问全局变量是众多bug的根源。务必慎用全局变量。

“遮盖”的问题

读取全局变量的值通常不会有问题,但还是存在出现问题的可能性。如果有一个局部变量或参数与你要访问的全局变量同名,就无法直接访问全局变量,因为它被局部变量遮住了。

如果需要,可使用函数globals来访问全局变量。这个函数类似于vars,返回一个包含全局变量的字典。(locals返回一个包含局部变量的字典。)

例如,在前面的示例中,如果有一个名为parameter的全局变量,就无法在函数combine中访问它,因为有一个与之同名的参数。然而,必要时可使用globals()['parameter']来访问它。

>>> def combine(parameter):

... print(parameter + globals()['parameter'])

...

>>> parameter = 'berry'

>>> combine('Shrub')

Shrubberry

重新关联全局变量(使其指向新值)是另一码事。在函数内部给变量赋值时,该变量默认为局部变量,除非你明确地告诉Python它是全局变量。那么如何将这一点告知Python呢?

>>> x = 1

>>> def change_global():

...        globalx

...        x = x + 1

...

>>> change_global()

>>> x

2

作用域嵌套(闭包)

Python函数可以嵌套,即可将一个函数放在另一个函数内,如下所示:

def foo():

def bar():

print("Hello, world!")

bar()

嵌套通常用处不大,但有一个很突出的用途:使用一个函数来创建另一个函数。这意味着可像下面这样编写函数:

def multiplier(factor):

def multiplyByFactor(number):

return number * factor

returnmultiplyByFactor

在这里,一个函数位于另一个函数中,且外面的函数返回里面的函数。也就是返回一个函数,而不是调用它。重要的是,返回的函数能够访问其定义所在的作用域。换而言之,它携带着自己所在的环境(和相关的局部变量)!

每当外部函数被调用时,都将重新定义内部的函数,而变量factor的值也可能不同。由于Python的嵌套作用域,可在内部函数中访问这个来自外部局部作用域(multiplier)的变量,如下所示:

>>> double = multiplier(2)

>>> double(5)

10

>>> triple = multiplier(3)

>>> triple(3)

9

>>> multiplier(5)(4)

20

像multiplyByFactor这样存储其所在作用域的函数称为闭包。

通常,不能给外部作用域内的变量赋值,但如果一定要这样做,可使用关键字nonlocal。

这个关键字的用法与global很像,让你能够给外部作用域(非全局作用域)内的变量赋值。

标签:闭包,...,函数,作用域,python,全局变量,parameter,def

来源: https://blog.csdn.net/jamfiy/article/details/87949715

更多相关推荐

python中局部变量的作用域_pytho...

FOLLOWME一、局部变量局部变量只在函数内生效,这个函数就是这个变量的作用域。这个变量的作用...

继续阅读

python函数作用域包括局部变量和...

您的“关注”和“点赞”,是信任,是认可,是支持,是动力…如意见相佐,可留言。本人必将竭尽全力...

继续阅读

python变量作用域图解_图解pytho...

这篇文章主要介绍了图解python全局变量与局部变量相关知识,文中通过示例代码介绍的非常详细,...

继续阅读

python变量作用域和生存期_Pytho...

一、引用全局变量使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关...

继续阅读

python类中变量作用域_Python15...

1.deftest(name):print('before',name)name='22'#该name变量属于局部变量,只在该函数中生效;...

继续阅读

python函数中变量的作用域_异常...

背景:我正在用Python对NationalTest’sTestStand进行COM编程.TestStand抱怨是否没有正确“释放”...

继续阅读

python函数变量作用域(全局变量...

一、引用全局变量使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关...

继续阅读

python函数作用域_Python函数的...

作用域规则命名空间是从名称到对象的映射,Python中主要是通过字典实现的,主要有以下几个命名...

继续阅读

python闭包变量作用域_Python学...

一、全局变量与局部变量一个模块中,最高级别的变量有全局作用域。全局变量一个特征就是:除非...

继续阅读

Python中变量作用域问题——局部变...

参考文章1:红黑联盟1,关于几种函数的简称(非原创)L:local,局部作用域,即函数中定义的变...

继续阅读