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


  • 相关阅读:
    游戏中心 & 内购
    使用storyboard显示UITableView时,如果不修改系统默认生成的tableView:cellForRowAtIndexPath:方法中的代码,则必须为UITableViewCell注册(填写)重用标识符:identifier.必须要代码方法中的标识符一致.
    《Linux就该这么学》学习记录
    《CSS世界》学习记录
    2019年书摘汇总
    《花间集》书摘
    《小山词》书摘
    《云边有个小卖部》书摘
    《喜宝》书摘
    《夏摩山谷》书摘
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3037457.html
Copyright © 2011-2022 走看看