zoukankan      html  css  js  c++  java
  • Python作用域的规则小析

     Python的作用域解析是基于叫做LEGB(Local(本地),Enclosing(封闭),Global(全局),Built-in(内置))的规则进行操作的。这看起来很直观,对吧?事实上,在Python中这有一些细微的地方很容易出错。看这个例子:


    >>> x = 10
    >>> def foo():
    ... x += 1
    ... print x
    ...
    >>> foo()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in foo
    UnboundLocalError: local variable 'x' referenced before assignment

    这是怎么回事?

    这是因为,在一个作用域里面给一个变量赋值(注意这里是赋值,如果是被引用的话没有这个问题)的时候,Python自动认为这个变量是这个作用域的本地变量,并屏蔽作用域外的同名的变量。

    如果foo函数改成这个样子就没有问题:

    >>> def foo():
    ... y = x

    ... x = y+1
    ... print y

    很多时候可能在一个函数里添加一个赋值的语句会让你从前本来工作的代码得到一个UnboundLocalError。(感兴趣的话可以读一读这篇文章。)

    在使用列表(lists)的时候,这种情况尤为突出。看下面这个例子:


    >>> lst = [1, 2, 3]
    >>> def foo1():
    ... lst.append(5) # 这没有问题...
    ...
    >>> foo1()
    >>> lst
    [1, 2, 3, 5]

    >>> lst = [1, 2, 3]
    >>> def foo2():
    ... lst += [5] # ... 这就有问题了!
    ...
    >>> foo2()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in foo
    UnboundLocalError: local variable 'lst' referenced before assignment

    嗯?为什么foo2有问题,而foo1没有问题?

    答案和上一个例子一样,但是更加不易察觉。foo1并没有给lst赋值,但是foo2尝试给lst赋值。注意lst+=[5]只是lst=lst+[5]的简写,由此可以看到我们尝试给lst赋值(因此Python假设作用域为本地)。但是,这个要赋给lst的值是基于lst本身的(这里的作用域仍然是本地),而lst却没有被定义,这就出错了。

    http://blog.jobbole.com/68256/

  • 相关阅读:
    CI登录验证
    兼容所有浏览器的JS动态显示当前日期时间
    Active Record 数据库模式-增删改查操作
    数据库链接的增操作举例
    CI框架获取post和get参数 CodeIgniter
    PHP日期操作类代码-农历-阳历转换、闰年、计算天数等
    根据两点间的经纬度计算距离
    Session 类
    mysql 查询优化规则
    php获取文件夹下面的文件列表和文件夹列表
  • 原文地址:https://www.cnblogs.com/mycats/p/4416202.html
Copyright © 2011-2022 走看看