• 命名空间


    全局变量和局部变量

           全局变量:在函数外定义,在任何一个函数内都可使用。

      只在函数体内(某个范围)起作用的变量称为局部变量。

    >>> x = 2    # 全局变量
    >>> def func():
    ...     x = 9    # 局部变量
    ...     print('这是局部变量x=', x)
    ...
    >>> func()
    这是局部变量x= 9
    >>> print('这是全局变量x=', x)
    这是全局变量x= 2

      局部(函数内)作用域内声明全局变量:

    >>> x = 2
    >>> def func():
    ...     global x    # 在函数体内声明全局变量,即声明此处的x是全局变量
    ...     x = 9    # x是全局变量,修改的也是全局变量的值
    ...     print('这是局部变量x=', x)
    ...
    >>> func()
    这是局部变量x= 9
    >>> print('这是全局变量x=', x)
    这是全局变量x= 9

      如果函数内部没有global关键字,则函数内部对于全局变量能读取,不能重新赋值;当函数内部用global声明了全局变量后,才能在函数内部整体修改全局变量。

      而当全局变量是可变类型的对象时,在不用global关键字的情况下,依然是不能对可变类型的全局变量重新赋值,或者进行整体修改。但是却能够修改可变类型全局变量的内容,即对其内部进行操作。比如全局变量是个列表,在函数内部没有global的情况下,可以向此全局变量列表中增加或删除或修改列表中的内容。如果想将可变类型的全局变量整体修改了(或重新赋值),则依然要用global声明。

    >>> num = [22, 33, 55]    # 可变类型列表作为全局变量
    >>> def func():
    ...     num.append('python')    # 函数内实现对列表全局变量的修改
    ...
    >>> func()
    >>> print(num)
    [22, 33, 55, 'python']    # 局部内成功的修改了可变类型的全局变量

    >>> name = ['zhangsan', 'lisi']
    >>> def func():
    ...     name = ['wang', 'yang']   # 函数内对列表重新赋值,不能改变全局变量,此处为新的同名变量
    ...     print(name)    # 局部变量name
    ...
    >>> print(name)    # 打印全局变量name
    ['zhangsan', 'lisi']
    >>> func()
    ['wang', 'yang']    # 局部同名变量name
    >>> print(name)    # 全局变量不会被整体修改
    ['zhangsan', 'lisi']

    >>> name = ['zhangsan', 'lisi']
    >>> def func():
    ...     global name    # 加上global声明全局变量
    ...     name = ['wang', 'yang']    # 整体修改可变类型的全局变量
    ...     print(name)
    ...
    >>> print(name)    # 打印全局变量
    ['zhangsan', 'lisi']
    >>> func()    # 执行函数,全局变量被整体修改
    ['wang', 'yang']
    >>> print(name)    # 打印修改后的全局变量
    ['wang', 'yang']
    
    >>> def func():    # 定义删除列表全局变量中的元素的函数
    ...     del name[0]    # 删除列表全局变量的第一个元素
    ...
    >>> print(name)
    ['wang', 'yang']
    >>> func()
    >>> print(name)    # 列表全局变量内部被修改
    ['yang']

      操作列表全局变量时,运算符+和+=的区别:

    >>> num = [100, 'java']
    >>> def func(num):    # 定义函数,将列表全局变量num传给函数
    ...     num += num    # 实现了列表全局变量内部的修改,相当于num.append(num)
    ...     print(num)    # 打印的是修改后的列表全局变量
    ...
    >>> print(num)    # 打印原列表全局变量
    [100, 'java']
    >>> func(num)    # 执行函数,函数内列表全局变量内部会被修改
    [100, 'java', 100, 'java']
    >>> print(num)    # 打印修改后的列表全局变量
    [100, 'java', 100, 'java']
    
    >>> num = [100, 'java']
    >>> def func(num):    # 定义函数,将列表全局变量num传给函数
    ...     num = num + num    # 以这种方式,不会修改列表全局变量,而是新创建一个同名局部变量
    ...     print(num)    # 打印局部变量
    ...
    >>> print(num)    # 打印列表全局变量
     [100, 'java']
    >>> func(num)
    [100, 'java', 100, 'java']
    >>> print(num)    # 列表全局变量没有被修改
    [100, 'java']

    全局变量要慎用,因为这往往容易引起变量的混乱。

             全局变量全部大写;局部变量全部小写。

             局部变量和全局变量是在不同的范围内起作用,即变量产生作用的区域,简称作用域

    作用域

             python中的作用域属于静态作用域,即python中的变量作用域由它在程序中的位置决定的。

             python的作用域可划分为四个层级:

                      Local:局部作用域,或称为本地作用域。

                      Enclosing:嵌套作用域。

                      Global:全局作用域。

                      Built-in:内建作用域。

             对于一个变量,python是按照上述从前到后的顺序,在不同的作用域中查找。

             在python中,变量的作用域在函数、类中才能被改变。

    命名空间(Namespace)

             命名空间的分类:

                      本地命名空间(Function&Class: Local Namespace):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数结束或抛出了异常,则本地命名空间也结束了。

                      全局命名空间(Module: Global Namespace):每个模块创建自己所拥有的全局命名空间,不同模块的全局命名空间彼此相互独立,不会互相干扰。

                      内置命名空间:python运行起来,它们就存在了。内置函数的命名空间都属于内置命名空间,所以我们可以在任何程序中直接运行它们。

             三种命名空间从里到外的顺序是本地命名空间、全局命名空间、内置命名空间。

             访问本地命名空间使用locals(),访问全局命名空间使用globals()。命名空间中的数据存储结构和字典是一样的。

    对于不同的命名空间,有不同的查找顺序(从里到外)和不同的生命周期

    作用域综合:

      在局部中直接使用全局变量:

    >>> x = 2    # 全局变量
    >>> def func(y):
    ...     print(x+y)    # 函数中直接使用全局变量
    ...
    >>> func(7)
    9

    警告:像这样在局部中直接使用全局变量的方式是众多bug的根源,务必慎用全局变量。

    局部中定义同名变量,覆盖全局变量:

    >>> x = 2    # 全局变量
    >>> def func(y):
    ...     x = 9    # 局部变量
    ...     print(x+y)
    ...
    >>> func(9)
    18
    >>> print(x)    # 全局域中,x是全局变量
    2

    局部中声明全局变量:

    >>> x = 2
    >>> def func(y):
    ...     global x    # 函数内声明全局变量
    ...     x = 9    # 这是全局变量
    ...     print(x+y)
    ...
    >>> func(9)
    18
    >>> print(x)
    9

      在全局中可使用globals()来访问全局变量,这个函数类似于函数vars()在全局中,返回一个包含全局变量的字典。

    >>> globals()     # 返回一个包含全局变量的字典
    {'__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'func': <function func at 0x7f34c0a30840>, '__spec__': None, 'name': 'Jack', '__package__': None, '__name__': '__main__', '__doc__': None, 'x': 9, '__builtins__': <module 'builtins' (built-in)>}
    >>> globals()['name']    # 从返回的包含全局变量的字典中取出数据
    'Jack'
    >>> vars()    # 类似于vars()在全局中
    {'__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'func': <function func at 0x7f34c0a308c8>, '__spec__': None, 'name': 'Jack', '__package__': None, '__name__': '__main__', '__doc__': None, 'x': 9, '__builtins__': <module 'builtins' (built-in)>}
    >>> vars()['name']
    'Jack'

      在局部中可使用locals()返回一个局部变量的字典。类似于函数vars()在局部中。

    >>> def func():
    ...     age = 22
    ...     lang = 'python'
    ...     print(locals())    # 返回一个包含局部变量的字典
    ...     print(vars())    # 类似于vars()在局部中
    ...
    >>> func()
    {'age': 22, 'lang': 'python'}
    {'age': 22, 'lang': 'python'}

    Help on built-in function vars in module builtins:

     

    vars(...)

        vars([object]) -> dictionary

     

        Without arguments, equivalent to locals().

    With an argument, equivalent to object.__dict__.

  • 相关阅读:
    EF Core 小技巧:迁移已经应用到数据库,如何进行迁移回退操作?
    ABP Framework 5.0 RC.1 新特性和变更说明
    OI迷惑行为大赏【目前较少,持续更新中】
    【比赛日志】APIO2020(2020.08.15)
    【好题】【IPSC2003】 Got Root? 无向图删边游戏
    [HNOI2019] 校园旅行 —— 一个边界数据
    【题解】JOISC 2020 Day 3 stray
    ExtJS学习:MVC模式案例(四) 林枫705
    ExtJS学习:MVC模式案例(三) 林枫705
    ExtJS学习:MVC模式案例(二) 林枫705
  • 原文地址:https://www.cnblogs.com/wgbo/p/9663004.html
Copyright © 2020-2023  润新知