python学习笔记

1. import 仅在第一次有效。

在交互提示符中通过import一个文件来运行它,但仅会在一次会话中起一次作用,接下来的import仅仅是返回这个已加载的模块。若要强制python重新加载一个文件的代   码,需要调用函数reload(module)来达到这个目的。

2. 使用简单的for循环而不是while或者range

S = "hello world"
for c in S: print c                           #简洁
for i in range(len(S)): print S[i]            #复杂
i = 0
while i < len(S): print S[i]; i+=1            #复杂

3. 改变对象的函数的返回值为None.

比如list.append()或者list.sort(), 会修改list对象,并且不会将修改后的对象返回,而是返回None.

D = {"a":1, "b":2, "c":3}
for k in D.keys().sort(): print D[k]

上述代码的作用是先对字典里item按key进行排序,再依次打印出key所对应的value值。但实际上述代码并不能按期望执行,因为.sort()返回的是None而不是list对象。

k = D.keys()
ks = k.sort()
for k in ks: print D[k]

4. 赋值语句不会创建对象副本,仅创建引用。

A = [1, 2, 3]
B = [2, A, 5]

则改变A,B中A所表示的部分也会被改变。为避免A改变,B中A所指示的部分也跟着变,可以通过创建一个副本来避免共用的引用。

B = [2, A[:], 5]

5. 静态识别本地域的变量名。

python 默认将一个函数中赋值的变量名视作是本地域的,它存在于该函数的作用域中并且在函数运行时才才在。

x = 2
def func():
  print x
  x = 4
>> func()

在运行func()时,会报错“未定义变量”。因为python是在编译def代码时,去静态识别本地变量,而不是在运行是碰到赋值的时候才识别。在编译时,python碰到给x赋值的语句时,认为这个函数中的任何地方的x会被视为一个本地变量,但真正运行函数时,执行print语句时,赋值语句还没有发生,这时python会报告”未定义变量名“的错误。

6. 默认参数和可变对象

在执行def语句时,默认参数的值只被解析并保存一次,而不是每次在调用函数的时候。

>>def saver(x=[]):
       x.append(1)
       print x
>>saver([2])
[2, 1]
>>saver()
[1]
>>saver()
[1, 1]
>>saver()
[1, 1, 1]

可变默认参数在每一次函数调用的时候保持了他们的状态。

为摆脱上述行为,可做如下修改:

def saver(x=None):
    if x == None: x = []
    x.append(1)
    print x

 7. python作用域规则

python的作用域解析基于LEGB(Local(本地), Enclosing(封闭),Gobal(全局),Build-in(内置))的规则进行的。

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

出现上述报错是因为,在一个作用域里面给变量赋值时,python自动认为这个变量时这个作用域的本地变量,并屏蔽作用域外的同名的变量。在使用列表(list)时,这种情况尤为突出。

>>> list1 = [1, 2, 3]
>>> def test1():
          list1.append(5)
>>> test1()
>>> list1
[1, 2, 3, 5]
>>> list2 = [1, 2, 3]
>>> def test2():
          list2 += [5]
>>> test2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in test2
UnboundLocalError: local variable 'list2' referenced before assignment

test1无错,test2有错的原因是test1没有给list1赋值,test2尝试给list2赋值。由于python假设作用域为本地,test2中要赋给list2的值是基于list2本身的,而list2没有定义,故报错。

8. 在遍历表的同时修改表。

>>> odd = lambda x : bool(x%2)
>>> numbers = [n for n in range(10)]
>>> for i in range(len(numbers)):
          if odd(numbers[i]):
            del numbers[i]     #不应在遍历列表的同时删除列表的元素
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range

可以用更加优雅的代码完成上述功能

>>> odd = lambda x : bool(x%2)
>>> numbers = [n for n in range(10)]
>>> numbers[:] = [n for n in numbers if not odd(n)]
>>> numbers [0,
2, 4, 6, 8]

9. range与xrange的区别

range会返回一个list对象,而xrange每次调用返回其中的一个值,因此做循环时xrange的性能要好一些。

 

参考:

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

http://blog.jobbole.com/69834/

posted @ 2014-10-21 23:42  darlwen  阅读(170)  评论(0编辑  收藏  举报