zoukankan      html  css  js  c++  java
  • [置顶] 十个Python陷阱(13)

    这些陷阱不一定是语言的缺陷,然而,这些语言的副作用,常常会使新手绊倒,甚至是有经验的程序员也会中招。完全理解Python的一些核心行为,反而可能会使你陷入其中。

    这边文章类似于一个对Python初学者的指导,早点了解这些陷阱,总比在实际项目的deadline前遭遇他们要好吧 :-)这不是在批评Python语言,就像前面说的,大部分的陷阱并不是由于语言的缺陷。


    1. 不一致的缩进

    好吧,先来个简单的。但是,学习其他“空格无关”的语言的新手,就会因为他们的坏习惯被Python惩罚。

    解决方法:统一的缩进,全部使用空格或制表符(tab),不要混淆使用。一个好的编辑器会很有帮助。


    2. 赋值、别名、对象

    先学习过某些静态语言比如Pascal和C的同学,经常会假设Python变量和赋值的工作机制和它们一样,乍一看上去,确实一样:

    a = b = 3
    a = 4
    print a, b  # 4, 3

    然而,在变长对象这里却会出问题,那是因为Python对变长对象和定长变对象是不同的。

    a = [1, 2, 3]
    b = a
    a.append(4)
    print b
    # b is now [1, 2, 3, 4] as well

    这是怎么回事?一个声明语句a = [1, 2, 3]做了两件事:1. 创建一个对象(一个list)并赋值为[1, 2, 3];2. 在本地命名空间中将a绑定到改变量上。b = a 将b绑定到相同的list(已经被a引用的)上。一旦你意识到这个,理解a.append(4)的行为就简单多了,它改变了被a和b引用的list的值。

    关于定长对象和变长对象在赋值时表现不同的说法事实上是不对的。当a = 3 b = a,这时a和b都引用了同一个对象——一个值为3的整数对象,但是,因为整数对象是不可变的,你并不会陷入到陷阱中。

    解决方法:使用拷贝方法,切片操作符等,Python从不隐式拷贝。Read this.


    3. +=操作符

    诸如C之类的语言,+=是一个简化表达式的运算符,例如:

    x += 42;

    是下面的表达式的简化:

    x = x + 42;

    所以,你可能认为在Python中也是一样的。当然,初看上去确实一样:

    a = 1
    a = a + 42
    # a is 43
    a = 1
    a += 42
    # a is 43

    然而,对于变长对象,x += y 跟 x = x + y不完全相同。考虑list:

    >>> z = [1, 2, 3]
    >>> id(z)
    24213240
    >>> z += [4]
    >>> id(z)
    24213240
    >>> z = z + [5]
    >>> id(z)
    24226184

    x += y 就地改变了list的值,而x = x + y创建了一个新的list并重新将x绑定上去。一个细微的差别可能导致难以追踪的BUG。

    不仅仅是这些,当混合使用定长对象和变长对象的时候,你会有更加惊奇的发现:

    >>> t = ([],)
    >>> t[0] += [2, 3]
    Traceback (most recent call last):
      File "<input>", line 1, in ?
    TypeError: object doesn't support item assignment
    >>> t
    ([2, 3],)

    明显的,元组不支持对其中元素的赋值——但是在对他使用+=后,元组里的list确实改变了!原因依然是+=就地改变list的值。但是元组的赋值不被允许,当异发生时,元组中的list已经被就地改变了。

    这就是一个我个人觉得非常致命的陷阱。

    解决方法:干脆避免使用+=,或者仅仅在整数时使用它。:-)


    原文:http://zephyrfalcon.org/labs/python_pitfalls.html


  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3037457.html
Copyright © 2011-2022 走看看