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的性能要好一些。
参考: