python学习日记(更新到2013年7月4日)

学习Python日记奋斗


读完啦,虽然后面的总结部分快速扫过,没有仔细看。

个人感觉就是,光看书没用,必须要手动写python代码才行。


学习python的中文书都不怎么样,英文的看上去又费劲,幸好网络资源丰富,完全足够了

这本书非常好

深入Python(中文版)

这个教程写的比较通俗简单(我就喜欢老外的这种教程风格,语气谦虚好玩不装B)。教程里面有很多“进一步阅读”的链接,真的非常棒,强烈推荐都读一遍,虽然都是英文的看着累,但是绝对值得。


嗯,接下来我就主要记录一下一些我觉得有价值的东西吧


一、重要概念

1. 代码风格

Google开源项目风格指南(Python)

这个对于python代码风格讲的非常清楚,在学习一门语言之前最好先了解一下这门语言的编程风格


2. import机制

读官方文档

http://docs.python.org/2/tutorial/modules.html#SECTION008410000000000000000

官方文档主要讲解的是原理,不太好理解,建议再随便搜几篇国人写的import总结看看。弄懂import对于以后python开发非常重要。


3. Python的类和对象

也是书中推荐的一个阅读资料,详细说明了python语言的面向对象编程与其他语言的不同点,例如为什么每个类方法必须要有self参数,python的多态不需要类有继承关系等等。

http://www.freenetpages.co.uk/hp/alan.gauld/tutclass.htm


二、编程技巧

1. 分片(slice)

分片会产生新的对象,例如:

li=[1, 2, 3]

li[:]虽然也是[1,2,3],但他是li的一份复制,这个通常被用在for循环需要修改遍历对象的时候,例如:

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

(摘自http://docs.python.org/2/tutorial/controlflow.html#SECTION006710000000000000000


2.with回收资源

下面的语句没有考虑当使用完f后关闭文件句柄

for line in open("myfile.txt"):
    print line,

可以借助with实现

with open("myfile.txt") as f:
    for line in f:
        print line,
(摘自 http://docs.python.org/2/tutorial/errors.html#SECTION0010400000000000000000


3. 负数index

负数index算是python里面一个比较有特色的语法,但我一直不理解干嘛要支持负数作为索引?难道只是为了多一个语法上的trick吗?后来看别人代码的时候终于明白了。

假设你有一个list,而且不断调用append向list尾部添加元素。如果要快速获取list尾部那个值就正好可以使用这个技巧了。例如:

li=[]

li.append(1)

li[-1]是1

li.append(2)

li[-1]是2

index为-1的值就是尾部的数据,这样写真是太方便了(同样的功能,相比与java或c++来说)


4. 非转义字符穿

在python中,“\”(反斜杠)默认是转义字符,所以如果要表示一个“\”应该写成"\\"。当反斜杠经常出现的时候(例如正则表达式),这种做法会让人崩溃。还好python可以通过在字符串之前添加r,来表示这个字符串不转义。例如:

r'\hello\world\\\\\'


5. 用名字动态加载类

利用globals()方法,可以用名字找到类,从而便于动态加载类和实例化对象。这样做比一对if语句或是case语句好多了(哦对了,python没有case语句)。举个例子:

parseName = "%sDialectizer" % dialectName.captialize()

parserClass = globals()[parserName]

parser = parserClass()

第一行,将dialectName字符串改为首字母大写,其他部分小写的形式,然后和Dialectizer拼接成parserName

第二行,调用globals()方法在全局环境中找到parserName对应的类

第三行,实例化该类,得到对象

这样做,如果以后parserClass扩展了很多,也不需要对源代码进行修改,只需要修改dialectName的值,这个代码就可以自动找到合适的类来使用。


6. 动态函数

第17章动态函数一章讲了很多非常cool的技巧。光看这些就让我满头大汗




三、需要注意的问题

1. import机制中,首先查找built-in模块,接着查找文件所在路径的模块,最后查找python环境变量中的模块。因此如果文件路径下的模块和python环境变量中的模块重名,则会优先使用当前路径下的模块。

这和shell脚本的命令搜索顺序类似,需要注意


2. python的垃圾回收机制中,对于两个对象相互引用的情况,python是可以识别出来的,但是如果他们定义了__del__方法(类似析构函数),则python无法将他们释放,因为python不知道应该按照什么顺序调用__del__方法。

避免这种问题的方法是,当出现对象间相互引用时,不要给他们定义__del__函数


3. python中的对象间赋值操作(=操作)实际上是复制引用,并不会赋值对象,java程序员会有深刻感触。但是python太极端了,一切皆对象,有时候就会出现一些问题。

比如:

def f(a = []):

    a.append(0)

    return a

如果连续调用3次该函数,得到的返回值不是[0],[0],[0],而是[0],[0,0],[0,0,0]

这是因为函数f是对象,参数a是f对象的一个属性,碰巧该属性是类属性(类似静态变量的概念),于是每次调用f的时候a都被修改了。

避免这种问题的方法是,如果函数有带默认值的参数,应该避免直接修改该参数


4. 单元测试的设计原则

书中对于单元测试部分的内容说的很有趣。

例如,单元测试为什么如此重要:

代码开发之前,强迫你以有效的方式考虑需求的细节

代码开发中,防止过度开发。通过了所有测试,开发就应该完成了

重构代码时,确保新版和旧版功能一致

维护代码时,当你的代码更改导致别人代码出问题时帮你留住面子(“但是先生,我check in代码时所有的单元测试都通过了。。。”)大笑

团队开发时,可以使你有信心,保证自己提交的代码不会破坏其他人的代码,因为你可以先运行其他人的测试代码。

单元测试分为:

正面测试——验证合法输入是否产生正确结果

反面测试——验证非法输入是否产生预期的失败

完备性检测——如果一组代码中包含互逆的转换函数,一个把A转换成B,另一个把B转换成A,在这种情况下,创建“完备性检测”可以使你由A转B再转A的过程中不会出现精度丢失或取整等错误

一个单元测试用例应该做到:

完全独立运行,不需要人工输入。单元测试应该是自动的。

可以自己判断被测试函数是通过还是失败,不需要人工干预结果。

独立运行,可以与其他测试用例隔离。每个测试用例是一个孤岛,例如A函数的输入依赖B函数的输出,那么当测试A函数时,应该手工构造输入而不是调用B函数

每个测试用例只回答一个问题。想象一下,如果你在一个测试用例中进行了好几种测试,那么如果测试失败,你不得不分析测试用例来找出问题的原因,这无疑是一个失败的设计。


四、其他

1. 书中一些好玩的句子:

第324页,在简单交代了列表解析的几个方案后,作者写到:“好了,玩够了。让我们来看一些真实的代码。”

第327页,在动态导入技术代码的注视中,作者写道:“你的路径可能不同,这取决于你的操作系统、你安装python的位置、月亮残缺的程度等等。”



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值