• Python一些难以察觉的错误


    Python一些难以察觉的错误

    今天把微博的收藏夹打开,发现以前很多收藏的好文章还没有细细研究,今天开始要慢慢研究总结总结。今天看的这篇文章地址:
    http://blog.amir.rachum.com/blog/2013/07/06/python-common-newbie-mistakes-part-1/
    http://blog.amir.rachum.com/blog/2013/07/09/python-common-newbie-mistakes-part-2/

    关于作用域

    这个实际上是上述链接中的第二篇文章中的内容,我之所以先拿出来说是因为最近在手写一个简单的Python解释器,突然看到这个点觉得非常好理解。
    首先给出出错代码:

    bar = 42
    def foo():
        print bar
        if False:
            bar = 0
    >>> foo()
    Traceback (most recent call last):
      File "<pyshell#17>", line 1, in <module>
        foo()
      File "<pyshell#16>", line 3, in foo
        print bar
    UnboundLocalError: local variable 'bar' referenced before assignment
    

    我们可以看到,第3行的print bar出错了,可是明明有一个全局变量bar啊!实际上,Python在解释程序前会进行各种处理,其中有一个部分叫做【静态检查】,其部分作用就是建立一个作用域的栈(注意:此时代码并没有执行,解释器只是在扫描代码而已)。虽然,第3行执行时,局部变量bar = 0这句不会被执行,但是在静态检查阶段,依然会将局部变量bar压入作用域栈,因此在执行时,print bar先检查作用域栈,而此时的栈顶元素肯定是局部变量bar而非全局变量bar,而局部变量永远没有机会声明,所有这句会出错。实际上将代码变成下面这样也一样会出错:

    bar = 42
    def foo():
        print bar
        bar = 0
    

    出错原因是局部变量bar先使用后再赋值。
    那么如何避免这个问题呢?原文作者给出了两个解决方法:

    1. 使用global关键词,将局部变量明确声明为全局变量
    2. 将全局变量作为类的属性。

    使用可变值类型作为函数默认参数

    学过python都知道,可变值只list、dict等这类可以修改值的类型,而像元组、int等都是不可变的。

    def foo(numbers=[]):
        numbers.append(9)
        print numbers
    

    当函数foo调用时传入非空参数是,函数的动作非常正常,而当我们使用默认参数时就能发现问题:

    >>> foo() # first time, like before
    [9]
    >>> foo() # second time
    [9, 9]
    >>> foo() # third time...
    [9, 9, 9]
    >>> foo() # WHAT IS THIS BLACK MAGIC?!
    [9, 9, 9, 9]
    

    我们的期望是每次调用foo()都只输出[9]啊!!!解释这个现象的关键点是:在Python里,函数的默认值是在函数定义的时候实例化的,而不是在调用的时候。而在每一次调用函数时,这个值都会存储起来,如果值没有变化,调用时也引用这个值。

    类似情况,如果我们这样定义函数:

    def print_now(now=time.time()):
        print now
        
    >>> print_now()
    1416878890.67
    >>> print_now()
    1416878890.67
    

    每次调用的结果相同,因为time.time()的结果是可变的,因此now的默认值是声明时的结果。

  • 相关阅读:
    Action获取表单数据的三种方式
    Action三种编写方式
    hibernate 查询方式
    hibernate 多对多操作(级联操作)
    对拍
    树的数据生成器
    SPOJ1825 Free tour II 树分治
    Codeforces 474(#271 Div 2) 解题报告
    HNCPC2012 总结
    Sort 对下标进行排序
  • 原文地址:https://www.cnblogs.com/jaletech/p/some-of-the-Python-errors.html
Copyright © 2020-2023  润新知