包管理 在requirements.txt文件中列出项目所需要的包。每个包占一行,通常还包含版本号。 例如: pelican==3.3 Markdown Python函数参数默认值的陷阱和原理深究 def generate_new_list_with(my_list=[], element=None): my_list.append(element) return my_list list_1 = generate_new_list_with(element=1) #print(list_1) list_2 = generate_new_list_with(element=2) #print(list_2) 在上述的例子中,输出list_2会发现参数my_list[]的列表中包含了list_1的初始化值, 解释: 可见代码运行结果并不和我们预期的一样。list_2在函数的第二次调用时并没有得到一个新的list并填入2,而是在第一次调用结果的基础上append了一个2。为什么会发生这样在其他编程语言中简直就是设计bug一样的问题呢? 可见如果参数默认值是在函数编译compile阶段就已经被确定。之后所有的函数调用时,如果参数不显示的给予赋值,那么所谓的参数默认值不过是一个指向那个在compile阶段就已经存在的对象的指针。如果调用函数时,没有显示指定传入参数值得话。那么所有这种情况下的该参数都会作为编译时创建的那个对象的一种别名存在。如果参数的默认值是一个不可变(Imuttable)数值,那么在函数体内如果修改了该参数,那么参数就会重新指向另一个新的不可变值。而如果参数默认值是和本文最开始的举例一样,是一个可变对象(Muttable),那么情况就比较糟糕了。所有函数体内对于该参数的修改,实际上都是对compile阶段就已经确定的那个对象的修改。 单下划线_ 在解释器中:在这种情况下,“_”代表交互式解释器会话中上一条执行的语句的结果。这种用法首先被标准CPython解释器采用,然后其他类型的解释器也先后采用。 名称前面加双下划线 为了避免与子类定义的名称冲突,不能轻易覆写本方法, 名称前后的双下划线 一种惯例,通常需要覆写本方法。目的是为了不会与用户自定义的名称冲突。 隐藏方法:函数unpack def foo(x, y): print x, y alist = [1, 2] adict = {'x': 1, 'y': 2} foo(*alist) # 1, 2 foo(**adict) # 1, 2 隐藏特性 2, 链式比较操作符 >>> x = 3 >>> 1 < x < 5 True >>> 4 > x >=3 True 隐藏特性 3,函数的默认参数 >>> def foo(x=[]): ... x.append(1) ... print x ... >>> foo() [1] >>> foo() [1, 1] 更安全的做法是: >>> def foo(x=None): ... if x is None: ... x = [] ... x.append(1) ... print x ... >>> foo() [1] >>> foo() [1] >>>