• Python之作用域


    作用域测试例子:

    >>> a = 10
    >>> def test():     
    ...     a = 20      
    ...     print a
    ... 
    >>> a
    10
    >>> test()
    20
    >>> a #执行test之后,a的值还是10,没有变
    10

    这里涉及作用域问题。

    作用域

    函数形参和内部变量都存储在locals名字空间中。

    >>> def test(a,*args,**kwargs):
    ...     s = "Hello test!"
    ...     print locals()
    ... 
    >>> test(1,"a","b",x=10,y="hi")
    {'a': 1, 's': 'Hello test!', 'args': ('a', 'b'), 'kwargs': {'y': 'hi', 'x': 10}}

    除非使用global、nolocal特别声明,否则在函数内部使用赋值语句,总是在locals名字空间中新建一个对象关联。注意:赋值是指名字指向新的对象,而非通过名字改变对象状态。

    回过头来看看上面的例子:

    >>> a = 10
    >>> def test():     
    ...     a = 20      
    ...     print a
    ... 
    >>> a
    10
    >>> test()  #两个x指向不同的对象
    20
    >>> a #外部变量没有被修改
    10

    如果仅仅是引用外部变量,那么按LEGB顺序在不同作用域查找该名字。

    名字查找顺序:
    locals ->enclosing function ->global ->__builtins__
    >>> a = 10
    >>> locals()
    {'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff578>, '__name__': '__main__', '__doc__': None}
    >>> 
    >>> def test():
    ...     a = 20
    ...     print locals()
    ...     print globals()
    ... 
    >>> globals() #和locals相同
    {'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff5f0>, '__name__': '__main__', '__doc__': None}
    >>> test()
    {'a': 20} #locals只有形参
    {'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff5f0>, '__name__': '__main__', '__doc__': None}

    *locals:函数内部名字空间,包括局部变量和形参

    *enclosing function:外部嵌套函数的名字空间

    *globals:函数定义所在模块的名字空间

    *__builtins__:内置模块的名字空间

    如果想将外部名字关联到一个新对象,就需要使用global关键字,指明要修改的是globals空间。

    >>> a = 10
    >>> def test():
    ...     global a #声明a,b是globals名字空间中的
    ...     global b
    ...     a = 20
    ...     b = 30
    ...     print "a in test= ",a
    ...     print "b in test=",b
    ... 
    >>> globals()
    {'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff2a8>, '__name__': '__main__', '__doc__': None}
    >>> test()
    a in test=  20
    b in test= 30
    >>> globals()
    {'a': 20, 'b': 30, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff2a8>, '__name__': '__main__', '__doc__': None}
    >>> if True:
    ...     a = 10
    ... 
    >>> globals()
    {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 10, '__package__': None}
    >>> if False:
    ...     b = 10
    ... 
    >>> globals()
    {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 10, '__package__': None}
    >>> def test():
    ... 
    KeyboardInterrupt
    >>> b
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'b' is not defined

    因为b变量对应的分支是False,不会产生b变量,而a不同,a已经在globals存在,故使用a没有问题,而使用b会出现错误。

  • 相关阅读:
    (一)版本控制管理器之发展史
    Mysql的binlog日志与mysqlbinlog命令
    centos下mysql中table大小写改为不敏感
    「Flink」RocksDB介绍以及Flink对RocksDB的支持
    redis事务
    零基础转行学习大数据技术需要经过哪些学习步骤?
    SQL Server解惑&mdash;&mdash;对象命名的唯一性小结
    泡泡后台Couchbase缓存使用经验分享
    MySQL_索引原理
    《分布式与云计算》MOOC第三单元课后测试答案
  • 原文地址:https://www.cnblogs.com/gsblog/p/3372866.html
Copyright © 2020-2023  润新知