深入了解python全局变量,局部变量和命名空间

目录
  • 函数中的全局和局部变量
  • 嵌套函数中的全局变量
  • 非局部变量

Python 使用全局和局部变量的方式是特立独行的。虽然在许多或大多数其他编程语言中,如果未另行声明,变量将被视为全局变量,而 Python 则以相反的方式处理变量。如果没有另外声明,它们是本地的。这种方法背后的驱动原因是全局变量通常是不好的做法,应该避免。在大多数情况下,您想使用全局变量,最好使用参数将值放入函数或返回值以将其取出。与许多其他程序结构一样,Python 也通过设计强加了良好的编程习惯。

因此,当您在函数定义中定义变量时,默认情况下它们是该函数的局部变量。也就是说,您对函数体中的此类变量所做的任何操作都不会影响函数外的其他变量,即使它们具有相同的名称。换句话说,函数体是这样一个变量的范围,即这个名称与其值相关联的封闭上下文。

所有变量都有块的作用域,它们在那里被声明和定义。它们只能在声明点之后使用。

简单说一下:变量不必也不能以在 Java 或 C 等编程语言中声明的方式声明。Python 中的变量通过定义它们来隐式声明,即第一次分配值到一个变量,这个变量被声明并自动具有必须分配给它的对象的数据类型。如果您在理解这一点时遇到问题,请参阅我们关于数据类型和变量的章节,请参阅左侧的链接。

函数中的全局和局部变量

在下面的示例中,我们想演示如何在函数体内使用全局值:

def  f ():
    print ( s )
s  =  “我爱夏天的巴黎!”
f ()

输出:

我爱夏天的巴黎!

在调用函数 f() 之前,变量 s 被定义为字符串“我爱夏天的巴黎!”。f() 的主体仅由“print(s)”语句组成。由于没有局部变量 s,即没有赋值给 s,将使用全局变量 s 的值。所以输出将是字符串“我爱夏天的巴黎!”。问题是,如果我们在函数 f() 中改变 s 的值会发生什么?它也会影响全局变量吗?我们在下面的一段代码中对此进行了测试:

def  f ():
    s  =  "我爱伦敦!"
    打印( s )
s  =  “我爱巴黎!”
f ()
打印( s )

输出:

我爱伦敦!
我爱巴黎!

如果我们将第一个示例与第二个示例结合起来,即我们首先使用 print() 函数访问 s,希望获得全局值,然后为其分配一个新值呢?给它赋值,意味着 - 正如我们之前所说的 - 创建一个局部变量 s。因此,我们会将 s 作为同一范围内的全局变量和局部变量,即函数体。幸运的是,Python 不允许这种歧义。因此,它会引发错误,正如我们在以下示例中所见:

def  f ():
   print ( s )
   s  =  “我爱伦敦!”
   打印( s )
s  =  “我爱巴黎!”
f ()

输出:

UnboundLocalError Traceback (最近一次调用最后一次)
<ipython-input-3-d7a23bc83c27> in <module>
5
6 s = “我爱巴黎!”
----> 7 f ( )
<ipython-input-3-d7a23bc83c27> in f ()
1 def f ( ) :
----> 2 print ( s )
3 s = “我
爱伦敦!” 4 打印( s )
5
UnboundLocalError:赋值前引用了局部变量“s”

变量不能在函数内既是局部的又是全局的。由于在 f() 内部为 s 赋值,因此 Python 决定我们需要一个局部变量,因此在 s 定义之前的第一个打印语句抛出了上面的错误信息。任何在函数内部更改或创建的变量都是局部变量,如果它没有被声明为全局变量。要告诉 Python,我们要使用全局变量,我们必须使用关键字“global”明确说明这一点,如下例所示:

def  f ():
    global  s
    print ( s )
    s  =  "只在春天,但伦敦也很棒!"
    打印( s )

s  =  "我在巴黎找课程!"
f ()
打印( s )

输出:

我正在巴黎寻找课程!
只在春天,但伦敦也很棒!
只在春天,但伦敦也很棒!

函数调用完成后,不能从外部访问函数的局部变量。这是上一个例子的延续:

def  f ():
    s  =  "我在全球范围内不为人知"
    打印( s )
f ()
打印( s )

输出:

我在全球不为人知
只在春天,但伦敦也很棒!

以下示例显示了局部和全局变量以及函数参数的狂野组合:

def  foo ( x ,  y ):
    全局 a
    a  =  42
    x , y  =  y , x
    b  =  33
    b  =  17
    c  =  100
    打印( a , b , x , y )
a ,  b ,  x ,  y  =  1 ,  15 ,  3 , 4
foo ( 17 ,  4 )
打印( a ,  b ,  x ,  y )

输出:

42 17 4 17
42 15 3 4

嵌套函数中的全局变量

如果我们在嵌套函数中使用 global 关键字,我们现在将检查会发生什么。以下示例显示了在各种范围内使用变量“city”的情况:

def  f ():
    city  =  "Hamburg"
    def  g ():
        global  city
        city  =  "Geneva"
    print ( "调用前g:"  +  city )
    print ( "现在调用g:" )
    g ()
    print ( "调用后g: "  + 城市)
f ()
print ( "主城的值:"  +  city )

输出:

之前打电话给g:汉堡
现在调用 g:
打电话后g:汉堡
主要城市价值:日内瓦

我们可以看到嵌套函数 g 中的 global 语句不会影响函数 f 的变量“city”,即它保持其值“Hamburg”。我们还可以从这个例子中推断出,在调用 f() 之后,模块命名空间中存在一个变量 'city',其值为 'Geneva'。这意味着嵌套函数中的 global 关键字不会影响其封闭命名空间的命名空间!这与我们在前一章中发现的一致:在函数内部定义的变量是局部变量,除非它明确标记为全局变量。换句话说,我们可以在任何封闭作用域中引用一个变量名,但我们只能在局部作用域中通过赋值重新绑定变量名,或者通过使用全局声明在模块全局作用域中重新绑定变量名。我们还需要一种方法来访问其他作用域的变量。这样做的方法是非局部定义,我们将在下一章解释。

非局部变量

Python3 引入了非局部变量作为一种新的变量。非局部变量与全局变量有很多共同点。与全局变量的一个区别在于,无法通过使用非局部语句来更改模块范围内的变量,即未在函数内部定义的变量。我们在以下两个示例中展示了这一点:

def  f ():
    全球 城市
    打印( city )
city  =  "法兰克福"
f ()

输出:

法兰克福

该程序是正确的,并返回“Frankfurt”作为输出。我们将在以下程序中将“全局”更改为“非本地”:

def  f ():
    非本地 城市
    打印( city )
city  =  "法兰克福"
f ()

输出:

文件“<ipython-input-9-97bb311dfb80>” ,第2
行 非本地城市
^
语法错误:未找到非本地“城市”的绑定

这表明非局部绑定只能在嵌套函数内部使用。必须在封闭的函数作用域中定义非局部变量。如果变量未在封闭函数作用域中定义,则变量不能在嵌套作用域中定义。这是与“全局”语义的另一个区别。

def  f ():
    city  =  "Munich"
    def  g ():
        nonlocal  city
        city  =  "Zurich"
    print ( "调用前g:"  +  city )
    print ( "现在调用g:" )
    g ()
    print ( "调用后g: "  + 城市)
city  =  "Stuttgart"
f ()
print ( "'city' in main:"  +  city )

输出:

打电话之前 g: 慕尼黑
现在调用 g:
拨打 g 后:苏黎世
主要的“城市”:斯图加特

在前面的例子中,变量 'city' 是在调用 g 之前定义的。如果没有定义,我们会得到一个错误:

高清 ˚F ():
    #city = “慕尼黑”
    高清 g ^ ():
        外地 市
        城市 =  “苏黎世”
    打印(“呼叫摹前:”  + 城市)
    打印(“立即致电G:” )
    g ^ ()
    打印(“后呼叫 g: "  +  city )
city  =  "Stuttgart"
f ()
print ( "'city' in main:"  +  city )

输出:

文件“<ipython-input-11-5417be93b6a6>” ,第4
行 非本地城市
^
语法错误:未找到非本地“城市”的绑定

该程序运行良好 - 如果我们将“非本地”更改为“全局”,在 f - 内有或没有 'city = "Munich"' 行:

def  f ():
    #city = "Munich"
    def  g ():
        global  city
        city  =  "Zurich"
    print ( "Before call g:"  +  city )
    print ( "Calling g now:" )
    g ()
    print ( "After 调用g:" )呼叫 g: " +  city )
city  =  "Stuttgart"
f ()
print ( "'city' in main:"  +  city )

输出:

打电话之前:斯图加特
现在调用 g:
拨打 g 后:苏黎世
主要的“城市”:苏黎世

然而有一个巨大的不同:全局 x 的值现在发生了变化!

(0)

相关推荐

  • python 中的命名空间,你真的了解吗?

    写在之前 命名空间,又名 namesapce,是在很多的编程语言中都会出现的术语,估计很多人都知道这个词,但是让你真的来说这是个什么,估计就歇菜了,所以我觉得 "命名空间" 有必要了解一下. 全局变量 & 局部变量 全局变量和局部变量是我们理解命名空间的开始,我们先来看一段代码: x = 2 def func(): x = 3 print('func x ---> ',x) func() print('out of func x ---> ',x) 这段代码输出的结

  • Python命名空间及作用域原理实例解析

    Python命名空间和作用域 总结 emmm,这一块讲了2个内容,一个是命名空间,一个是作用域.一个一个说吧 命名空间 A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries 上边这段是官方文档定义的,简单来说就是名字到对象的映射,我们知道,python的一切都是对象,你所定义的变量名其实只是个引用.这样就好理解了.python的

  • python基础之局部变量和全局变量

    四种基本的函数类型 局部变量 就是在函数内部定义的变量[作用域仅局限于函数内部] 不同的函数 可以定义相同的局部变量,但是各自用各自的 不会产生影响 局部变量的作用:为了临时的保存数据 需要在函数中定义来进行存储 全局变量 作用域为全局的变量 如果在函数内部想要对全局变量进行修改,必须使用Global关键字进行声明 局部变量 def printInfo(): name='peter' ##局部变量,只作用于printInfo函数,函数体之外无法使用 print('name') pass def

  • 浅析Python的命名空间与作用域

    名称空间 名称空间(namespaces):用于存放名字与内存地址绑定关系的地方,是对栈区的划分 作用:名称空间可以使栈区中存放相同的名字,从而解决命名冲突 名称空间分为三种: 内置名称空间 全局名称空间 局部名称空间 内置名称空间 内置名称空间:用于存放Python解释器中内置的名字 生命周期:Python解释器启动则产生,Python解释器关闭则销毁 例如:print.input.int ... 全局名称空间 全局名称空间:运行顶级代码所产生的名字,或者说除函数内定义以及内置的外,剩下的都是

  • Python中全局变量和局部变量的理解与区别

    前言 学过编程的人应该对全局变量与局部变量这两个名词并不陌生,Python也同多数编程语言一样,也有全局变量与局部变量的概念 但是与其他编程语言又有所不同 全局变量与局部变量两者的本质区别就是在于作用域 用通俗的话来理解的话, 全局变量是在整个py文件中声明,全局范围内都可以访问 局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了 如果在函数内部定义与某个全局变量一样名称的局部变量,就可能会导致意外的效果,可能不是你期望的.因此不建议这样使用,这样会使

  • Python局部变量与全局变量区别原理解析

    1.局部变量 name = "Yang Li" def change_name(name): print("before change:",name) name = "你好" print("after change", name) change_name(name) print("在外面看看name改了么?",name) 输出: before change: Yang Li after change 你好

  • 深入了解python全局变量,局部变量和命名空间

    目录 函数中的全局和局部变量 嵌套函数中的全局变量 非局部变量 Python 使用全局和局部变量的方式是特立独行的.虽然在许多或大多数其他编程语言中,如果未另行声明,变量将被视为全局变量,而 Python 则以相反的方式处理变量.如果没有另外声明,它们是本地的.这种方法背后的驱动原因是全局变量通常是不好的做法,应该避免.在大多数情况下,您想使用全局变量,最好使用参数将值放入函数或返回值以将其取出.与许多其他程序结构一样,Python 也通过设计强加了良好的编程习惯. 因此,当您在函数定义中定义变

  • 图解python全局变量与局部变量相关知识

    这篇文章主要介绍了图解python全局变量与局部变量相关知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 了解全局变量和局部变量之前,我们先来了解一下作用域 a = 10 def func(): b = 20 def inner(): c = 30 以上面这个程序为例:打印a,b,c 可以看到只有a打印 10 ,b和c都报错,这就是作用域的问题. 我们把新创建的一个.py文件看做事一个模块,在模块内定义的变量,如a,就是这个模块的全局变量,作

  • 解析python的局部变量和全局变量

    局部变量 什么是局部变量 通俗定义:函数内部定义的变量就叫局部变量. 话不多说,代码如下: def test1(): a = 300 # 定义一个局部变量a,并初始化300 print("--test1--修改前:a=%s" % a) a = 200 # 给变量a重新赋值200 print("--test1--修改后:a=%s" % a) def test2(): a = 400 # 定义另一个局部变量a,并初始化400 print("--test2--修

  • Python全局变量与局部变量区别及用法分析

    本文实例讲述了Python全局变量与局部变量区别及用法.分享给大家供大家参考,具体如下: 对于很多初学的同学,对全局和局部变量容易混淆,看看下面给大家的讲解相信都应该明白两者的区别了. 定义: 全局变量:在模块内.在所有函数的外面.在class外面 局部变量:在函数内.在class的方法内 下面来看看例子 一.函数内部调用全局变量 a="hello" #全局变量a def test(): global a#调用全局变量a b =a #test方法里之后再调用a时,都是全局的a prin

  • python函数局部变量用法实例分析

    本文实例讲述了python函数局部变量用法.分享给大家供大家参考.具体分析如下: 当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的.这称为变量的 作用域 .所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始. 一.使用局部变量 示例如下: #!/usr/bin/python # Filename: func_local.py def func(x): print 'x is', x x = 2 print 'Chang

  • Python全局变量用法实例分析

    本文实例讲述了Python全局变量用法.分享给大家供大家参考,具体如下: 全局变量不符合参数传递的精神,所以,平时我很少使用,除非定义常量.今天有同事问一个关于全局变量的问题,才发现其中原来还有门道. 程序大致是这样的: CONSTANT = 0 def modifyConstant() : print CONSTANT CONSTANT += 1 return if __name__ == '__main__' : modifyConstant() print CONSTANT 运行结果如下:

  • python全局变量引用与修改过程解析

    这篇文章主要介绍了python全局变量引用与修改过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if a == 1: print("a: %d" %a) for i in range(4): if i in b: print(&quo

  • Python 在局部变量域中执行代码

    问题 你想在使用范围内执行某个代码片段,并且希望在执行后所有的结果都不可见. 解决方案 为了理解这个问题,先试试一个简单场景.首先,在全局命名空间内执行一个代码片段: >>> a = 13 >>> exec('b = a + 1') >>> print(b) 14 >>> 然后,再在一个函数中执行同样的代码: >>> def test(): ... a = 13 ... exec('b = a + 1') ... p

  • Python全局变量global关键字详解

    Python中的变量作用域 一般在函数体外定义的变量成为全局变量,在函数内部定义的变量称为局部变量. 全局变量所有作用域都可用,局部变量只能在本函数可用,变量的使用顺序是,局部变量 > 全局变量, 也就是说:优先使用局部变量 那么问题来了, 如果想在函数内使用全局变量,或改变全局变量的值, 应该怎么做呢? Python全局变量global关键字 为了解决函数内使用全局变量的问题,python增加了global关键字, 利用它的特性, 可以指定变量的作用域. Python全局变量global关键字

  • Python全局变量关键字global的简单使用

    目录 简介: 案例1:全局无法使用局部变量. 案例2:全局变量,任意范围均可使用. 案例3:函数内定义的局部变量 案例4:函数间global关键字的作用 案例5:不同文件模块中的global,注意test6, test7为不同文件. 案例6:不同文件模块中的global,注意test6, test7为不同文件. 附:用global声明多个变量需要用逗号分 结论: 简介: 1.global是Python中的全局变量关键字. 2.全局变量是编程术语中的一种,源自于变量之分. 3.变量分为局部与全局,

随机推荐