Python中全局变量和局部变量的区别以及使用

作者:

文章目录
  • 定义:在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了,我们将这样的变量称为局部变量(Local Variable)。 理论:要知道,当函数被执行时,Python 会为其分配一块临时的存储空间,所有在函数内部定义的变量,都会存储在这块空间中。而在函数执行完毕后,这块临时存储空间随即会被释放并回收,该空间中存储的变量自然也就无法再被使用。 例子1: >>> def demo(): … text = “在函数内部声明了一个变量,这个变量就是局部变量” … print(text) … >>> demo() 在函数内部声明了一个变量,这个变量就是局部变量 >>> print(text) Traceback (most recent call last): File “<stdin>”, line 1, in <module> NameError: name ‘text’ is not defined 在上面的例子中,text变量的声明(创建)是在函数demo中,所以它是一个局部变量,所以在函数外面是不可以直接使用的。 如果试图在函数外部访问其内部定义的变量,Python 解释器会报 NameError 错误,并提示我们没有定义要访问的变量,这也证实了当函数执行完毕后,其内部定义的变量会被销毁并回收。
  • 除了在函数内部定义变量,Python 还允许在所有函数的外部定义变量,这样的变量称为全局变量(Global Variable)。 和局部变量不同,全局变量的默认作用域是整个程序,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用。 定义全局变量的方式有以下 2 种: 在main函数中定义的变量 在函数体内声明的全局变量
  • 在一些特定场景中,我们可能需要获取某个作用域内(全局范围内或者局部范围内)所有的变量,Python 提供了以下 3 种方式: globals()函数 locals()函数 vars(object)函数
  • 目录
    • 0. 前置知识
      • 0.1 作用域
    • 1. 局部变量
      • 1.1 问题一:同名变量
      • 1.2 问题二:函数调用函数外的变量
    • 2. 全局变量
      • 2.1 第一种声明方式 —— 在main函数中定义的变量
      • 2.2 第二种声明方式 —— 在函数体内声明的全局变量
        • 2.2.1 正确
        • 2.2.2 错误1 —— 没有调用函数就使用函数内部将会创建的全局变量
        • 2.2.3 错误2 —— 使用global关键字声明全局变量时直接对其进行赋值
        • 2.2.4 思考 —— 多个函数对同一变量进行全局变量声明会报错吗?
    • 3. 获取指定作用域范围中的变量
      • 3.1globals()函数
        • 3.2locals()函数
          • 3.3var(object)函数

          所谓作用域(Scope),就是变量的有效范围,就是变量可以在哪个范围以内使用

          • 有些变量可以在整段代码的任意位置使用
          • 有些变量只能在函数内部使用
          • 有些变量只能在 for 循环内部使用

          变量的作用域由变量的定义位置决定,在不同位置定义的变量,它的作用域是不一样的。在Python语言中,变量一般根据作用域被划分为两种:

          1. 局部变量
          2. 全局变量。

          定义:在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了,我们将这样的变量称为局部变量(Local Variable)。

          理论:要知道,当函数被执行时,Python 会为其分配一块临时的存储空间,所有在函数内部定义的变量,都会存储在这块空间中。而在函数执行完毕后,这块临时存储空间随即会被释放并回收,该空间中存储的变量自然也就无法再被使用。

          例子1

          >>> def demo():
          ...     text = "在函数内部声明了一个变量,这个变量就是局部变量"
          ...     print(text)
          ... 
          >>> demo()
          在函数内部声明了一个变量,这个变量就是局部变量
          >>> print(text)
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          NameError: name 'text' is not defined
          

          在上面的例子中,text变量的声明(创建)是在函数demo中,所以它是一个局部变量,所以在函数外面是不可以直接使用的。

          如果试图在函数外部访问其内部定义的变量,Python 解释器会报 NameError 错误,并提示我们没有定义要访问的变量,这也证实了当函数执行完毕后,其内部定义的变量会被销毁并回收。

          我们思考一个问题,如果在函数外部和函数内部都定义了同名变量,那么会怎么样呢?

          >>> def demo():
          ...     text = "在函数内部声明了一个变量,这个变量就是局部变量"
          ...     print(text)
          ... 
          >>> text = "在函数外部创建了同名变量"
          >>> demo()
          在函数内部声明了一个变量,这个变量就是局部变量
          >>> print(text)
          在函数外部创建了同名变量
          

          很明显,因为在函数外部定义了text变量,所以外部在调用text时不会调用函数内部的text而是调用前面我们定义的text

          那函数可以直接调用函数外的变量吗?

          >>> def demo():
          ...     print(f"函数直接调用外部变量 [{text}]")
          ... 
          >>> text = "在函数外部创建的变量"
          >>> demo()
          函数直接调用外部变量 [在函数外部创建的变量]
          

          可以看到,函数在直接定义时是可以调用外部变量的,且不会报错。当我们调用函数时,只要保证其调用的外部变量存在,则不会报错,否则就会报错。下面是报错的情况:

          >>> def demo():
          ...     print(f"直接调用main中的变量: {text}")
          ... 
          >>> # 此时main函数中并没有text变量
          >>> demo()
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
            File "<stdin>", line 2, in demo
          NameError: name 'text' is not defined
          

          除了在函数内部定义变量,Python 还允许在所有函数的外部定义变量,这样的变量称为全局变量(Global Variable)。

          和局部变量不同,全局变量的默认作用域是整个程序,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用。

          定义全局变量的方式有以下 2 种:

          1. 在main函数中定义的变量
          2. 在函数体内声明的全局变量

          其实我们在问题1.1和问题1.2中已经写了,在函数体外定义的变量其实就是全局变量,也就是在main函数中定义的变量就是全局变量。

          举个例子:

          >>> global_var_1 = "这是一个全局变量"
          >>> global_var_2 = ["这也是一个全局变量", 123]
          >>> # 再定义一个函数和局部变量
          >>> def demo(local_var_1, local_var_2):
          ...     local_var_3 = "这是一个局部变量"
          ...     local_var_4 = ("这也是一个局部变量", 456)
          ...     print(local_var_1)
          ...     print(local_var_2)
          ...     print(local_var_3)
          ...     print(local_var_4)
          ...     print("局部变量打印完毕")
          ... 
          >>> demo(1, 2)  # 这里传给函数的两个形参是全局变量
          1
          2
          这是一个局部变量
          ('这也是一个局部变量', 456)
          局部变量打印完毕
          >>> global_var_1
          '这是一个全局变量'
          >>> global_var_2
          ['这也是一个全局变量', 123]
          

          在函数体内也是可以创建全局变量的,步骤如下:

          def 函数名称(形参1, 形参2, ...):
          	# 1. 需在变量前使用关键字`global`进行声明,这样一个全局变量就创建好了
          	gloabl 全局变量名
          	# 2. 声明完毕后赋值
          	全局变量名 = 值
          
          # 3. 在调用函数之后,在函数中声明的全局变量也就被创建了,否则不会创建的
          函数名称(传参1,传参2)
          
          # 4. 可以任意使用那个全局变量了
          print(全局变量)
          

          >>> def demo():
          ...     # 声明一个局部变量var_1
          ...     var_1 = "This is a local variable"
          ...     # 1. 先用global关键词进行全局变量的声明
          ...     global var_2
          ...     # 2. 再对全局变量进行赋值
          ...     var_2 = "This is a global variable"
          ...     print(f"[在函数内使用] local_var: {var_1}")
          ...     print(f"[在函数内使用] global_var: {var_2}")
          ... 
          >>> demo()
          [在函数内使用] local_var: This is a local variable
          [在函数内使用] global_var: This is a global variable
          >>> # 在main函数中调用函数生成的全局变量
          >>> print(f"[在main函数中使用] global_var: {var_2}")
          [在main函数中使用] global_var: This is a global variable
          

          如果不调用函数就直接使用函数中创建的全局变量,是会报错的,如下:

          >>> def demo():
          ...     # 创建一个局部变量
          ...     var_1 = "局部变量123"
          ...     # 1. 先声明是全局变量
          ...     global var_2
          ...     # 2. 再进行赋值操作
          ...     var_2 = "全局变量456"
          ... 
          >>> # 如果不调用函数直接使用在函数中生成的全局变量
          >>> print(f"var_2: {var_2}")
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          NameError: name 'var_2' is not defined
          >>> # 必须先调用函数后,函数中的全局变量才能生成
          >>> demo()
          >>> print(f"var_2: {var_2}")
          var_2: 全局变量456
          

          >>> def demo():
          ...     # 如果声明时直接赋值
          ...     global var_1 = "这是一个全局变量,但是在声明时就赋值了"
            File "<stdin>", line 3
              global var_1 = "这是一个全局变量,但是在声明时就赋值了"
                           ^
          SyntaxError: invalid syntax
          

          看例子,很容易:

          >>> def func_1():
          ...     global var_1
          ...     var_1 = "abc"
          ...     print(f"[function_1]全局变量var_1已经创建: {var_1}")
          ... 
          >>> def func_2():
          ...     global var_1
          ...     var_1 = "123"
          ...     print(f"[function_2]全局变量var_1已经创建: {var_1}")
          ... 
          >>> # 其实没什么影响,和赋值的原理是一样的
          >>> # 先调用func_1
          >>> func_1()
          [function_1]全局变量var_1已经创建: abc
          >>> var_1
          'abc'
          >>> # 再调用func_2
          >>> func_2()
          [function_2]全局变量var_1已经创建: 123
          >>> var_1
          '123'
          

          在一些特定场景中,我们可能需要获取某个作用域内(全局范围内或者局部范围内)所有的变量,Python 提供了以下 3 种方式:

          1. globals()函数
          2. locals()函数
          3. vars(object)函数

          globals()函数为 Python 的内置函数,它可以返回一个包含全局范围内所有变量的字典,该字典中的每个键值对,键为变量名,值为该变量的值

          >>> globals()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'demo': <function demo at 0x7ff433a520d0>, 'var_2': '全局变量456', 'func_1': <function func_1 at 0x7ff433a52280>, 'func_2': <function func_2 at 0x7ff433a52160>, 'var_1': '123'}
          

          注意,globals()函数返回的字典中,会默认包含有很多变量,这些都是 Python 主程序内置的,不用理会它们。

          可以看到,通过调用 globals() 函数,我们可以得到一个包含所有全局变量的字典。并且,通过该字典,我们还可以访问指定变量,甚至如果需要,还可以修改它的值。例如,在上面程序的基础上,添加如下语句:

          >>> print(globals()["var_2"])
          全局变量456
          >>> globals()["var_2"] = "对这个全局变量进行重新赋值!"
          >>> print(globals()["var_2"])
          对这个全局变量进行重新赋值!
          >>> globals()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'demo': <function demo at 0x7ff433a520d0>, 'var_2': '对这个全局变量进行重新赋值!', 'func_1': <function func_1 at 0x7ff433a52280>, 'func_2': <function func_2 at 0x7ff433a52160>, 'var_1': '123'}
          

          locals() 函数也是 Python 内置函数之一,通过调用该函数,我们可以得到一个包含当前作用域内所有变量的字典。这里所谓的“当前作用域”指的是:

          • 在函数内部调用 locals() 函数,会获得包含所有局部变量的字典
          • 而在全局范文内调用 locals() 函数,其功能和 globals() 函数相同。
          >>> def demo(a, b):
          ...     c = 10  # 定义局部变量
          ...     global d  # 声明全局变量
          ...     d = 100
          ...     print(locals())  # 查看该函数的局部变量
          ...     return a + b + c + d
          ... 
          >>> # 定义一些全局变量
          >>> aaa = 123
          >>> bbb = 456
          >>> # 查看全局变量
          >>> globals()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'demo': <function demo at 0x7f1132cbd0d0>, 'aaa': 123, 'bbb': 456}
          >>> # 查看局部变量
          >>> locals()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'demo': <function demo at 0x7f1132cbd0d0>, 'aaa': 123, 'bbb': 456}
          >>> # 调用函数
          >>> demo(1, 2)
          {'a': 1, 'b': 2, 'c': 10}
          113
          >>> # 查看全局变量
          >>> globals()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'demo': <function demo at 0x7f1132cbd0d0>, 'aaa': 123, 'bbb': 456, 'd': 100}
          >>> # 查看局部变量
          >>> locals()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'demo': <function demo at 0x7f1132cbd0d0>, 'aaa': 123, 'bbb': 456, 'd': 100}
          

          Note:

          • 当使用 locals() 函数获得所有局部变量组成的字典时,可以向 globals() 函数那样,通过指定键访问对应的变量值,但无法对变量值做修改。

          vars() 函数也是 Python 内置函数,其功能是返回一个指定 object 对象范围内所有变量组成的字典。如果不传入object 参数,vars() 和 locals() 的作用完全相同

          >>> class A:
          ...     def __init__(self, a, b, c):
          ...             self.a = a
          ...             self.b = b
          ...             self.c = c
          ...     name = "Leovin"
          ...     school = "xxx University"
          ... 
          >>> print(f"vars(A): {vars(A)}")
          vars(A): {'__module__': '__main__', '__init__': <function A.__init__ at 0x7fd201d5e160>, 'name': 'Leovin', 'school': 'xxx University', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
          >>> print(vars())
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'A': <class '__main__.A'>}
          >>> print(globals())
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'A': <class '__main__.A'>}
          >>> print(locals())
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'A': <class '__main__.A'>}
          >>> def func(a, b):
          ...     c = 1
          ...     global d
          ...     d = 10
          ...     return a + b + c + d
          ... 
          >>> vars(func)
          {}
          >>> vars(func(1, 2))
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          TypeError: vars() argument must have __dict__ attribute
          >>> vars()
          {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'A': <class '__main__.A'>, 'func': <function func at 0x7fd201d5e0d0>, 'd': 10}
          >>> vars(A)
          mappingproxy({'__module__': '__main__', '__init__': <function A.__init__ at 0x7fd201d5e160>, 'name': 'Leovin', 'school': 'xxx University', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})
          

          到此这篇关于Python中全局变量和局部变量的区别以及使用的文章就介绍到这了,更多相关Python 全局变量和局部变量内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

          您可能感兴趣的文章:

          • Python中局部变量和全局变量举例详解
          • python中的全局变量与局部变量解读
          • Python变量教程之全局变量和局部变量
          • python基础之局部变量和全局变量
          • 浅析Python中全局变量和局部变量的使用
          • Python中全局变量和局部变量的理解与区别
          • Python局部变量与全局变量区别原理解析
          • 图解python全局变量与局部变量相关知识
          • 解析python的局部变量和全局变量
          • Python全局变量与局部变量区别及用法分析
          • 从局部变量和全局变量开始全面解析Python中变量的作用域

          站内搜索