├── 2 ├── Proposal10.py ├── Proposal11.py ├── Proposal12.py ├── Proposal13.py ├── Proposal14.py ├── Proposal15.py ├── Proposal16.py ├── Proposal17.py ├── Proposal18.py ├── Proposal8.py └── Proposal9.py └── README.md /2/Proposal10.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 10.充分利用Lazy evaluation的特性 4 | ############### 5 | # lazy evaluation被称为延时计算,指的是仅仅在真正需要执行的时候 6 | # 才计算表达式的值,好处体现在一下两个方面 7 | 8 | # 1.避免不必要的计算,带来性能上的提升 9 | from time import time 10 | from itertools import islice 11 | # 判断一个单词是不是指定的缩写形式 12 | t = time() 13 | abbreviations = ['cd.', 'e.g', 'ex.', 'etc.', 'fig.', 'i.e.', 'Mr', 'vs.'] 14 | for i in xrange (1000000): 15 | for w in ('Mr.', 'Hat', 'is', 'chasing', 'the', 'black', 'cat', '.'): 16 | if w in abbreviations: # 1.432502985 17 | # 表达式 x and y,当x为flases 表达式结果就为flase(and后面就不需要计算了) 18 | # 表达式x or y,当x为true 表达式的结果就为true 19 | #if w[-1] == '.' and w in abbreviations: # 1.10134792328 20 | pass 21 | print "用时:" 22 | print time()-t 23 | 24 | for w in ('Mr.', 'Hat', 'is', 'chasing', 'the', 'black', 'cat', '.'): 25 | print w[-1] 26 | 27 | # 2.节省空间,使得无限循环的数据结构成为可能 28 | def fib(): 29 | a, b =0, 1 30 | while True: 31 | yield a 32 | a, b =b, a+b 33 | print list(islice(fib(), 4))# 数字代表列表长度 34 | # 笔记 35 | # 1.如果对于or条件表达式应该将值为真可能性较高的变量写在or的前面,and则应该退后 36 | 37 | -------------------------------------------------------------------------------- /2/Proposal11.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 11.理解枚举替代实现的缺陷 4 | ############### 5 | """ 6 | 前言:枚举有很多的替代方法,但是或多或少都有一些缺陷,(允许枚举值重复,支持无意义操作) 7 | python2.7支持第三方模块flufl.enum,(可以通过pip安装)是实现枚举 8 | 不错的选择。 9 | """ 10 | from flufl.enum import Enum 11 | # 继承自Enum定义枚举,枚举值唯一 12 | #class Seasons(Enum): 13 | # Spring = 'Spring' #如果给spring赋值2,报错,值不能重复 14 | # Summer = 2 15 | # Autumn = 3 16 | # Winter = 4 17 | 18 | # 直接实例化Enum类 19 | Seasons = Enum('Seasons', 'Summer Summer Autumn Winter') #如果枚举中有重复则之显示一个,后一个覆盖前一个 20 | 21 | # flufl.enum 提供了__members__属性,可以对枚举名称进行迭代 22 | for member in Seasons.__members__: 23 | print member 24 | 25 | #可以直接使用value属性获取枚举元素的值 26 | print "Summer的值为:" 27 | print Seasons.Summer.value 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /2/Proposal12.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 12.不推荐使用type来进行类型检查 4 | ############### 5 | """ 6 | 前言:python作为动态性脚本语言,变量在定义时不需要指明具体类型。 7 | 为了充分利用其动态特征是不推荐进行类型检查的。如果两者之间, 8 | 类型不同又不能进行隐式类型转换(类如int+double转成double) 9 | 便抛出TypeError异常 10 | """ 11 | import types 12 | def add(a, b): 13 | return a+b 14 | 15 | print add(3, 4.1) #隐式类型转换 16 | # 不刻意进行类型检查,而是在出错的情况下通过抛出异常来进行处理。 17 | #print add(5, 'a') #抛出TypeError异常 18 | 19 | 20 | # 如果为了提高程序的健壮行,面临需要进行类型检查的情景。 21 | # 使用下面的方法进行,类型检查 22 | 23 | list1 = [] 24 | if type(list1) is types.ListType: #通过python自带的模块types中定义的名字进行比较 25 | print 'list1 is List' 26 | 27 | # 下面是使用type进行变量类型检查,会出现问题的两个示例: 28 | 29 | # 示例1: 30 | class TestInt(int): #TestInt类继承自int类 31 | pass # 什么都不做,不会报错 32 | 33 | n = TestInt() 34 | print type(n) is types.IntType #Flase 35 | # 由此可见基于内建类型扩展的用户自定义类型,type函数并不能准确返回结果 36 | 37 | # 示例2: 38 | class A: 39 | pass 40 | 41 | class B: 42 | pass 43 | 44 | a = A() 45 | b = B() 46 | 47 | print type(a) == type(b) #True 48 | 49 | # 这里有个疑问:如果我写成class A(object) 和class B(object) 50 | # 之后输出type(a) == type(b) 结果是Flase 为什么? 51 | 52 | 53 | # 使用isinstance()函数来解决以上两个示例: 54 | # isinstance()函数支持多种类型那个列表 55 | print isinstance(n, TestInt) # 这样就可以正确的显示34行的代码的类型了:True 56 | # 子类是的type等于父的,但是父类的不等于子类的 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /2/Proposal13.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 13.尽量转换为浮点类型后在做除法 4 | ############### 5 | """ 6 | 前言:当两个操作数都为整数的时候,其返回值也为证书,运算结果 7 | 将直接截断,从而在实际应用中造成潜在的误差。 8 | 9 | 所以:当涉及除法运算是尽量先将操作数转换为浮点类型在做运算。 10 | """ 11 | #from __future__ import division # __future__ 模块是为了方便从2.x到3.x的过渡,用于引入3.x的新特性 12 | 13 | 14 | # 方法1: 15 | gpa = (3+1) / 3 16 | 17 | real_gpa = float(3+1) / 3 # 通过强制转化为float类型 18 | 19 | print 'Wrong:', gpa,' Right:', real_gpa 20 | 21 | # 方法2: 22 | # 去掉第十一行开头的‘#’ 23 | gpa = (3+1) / 3 24 | 25 | print '使用python3中的division模块,实现精准除法,gpa=', gpa 26 | 27 | 28 | #注意:浮点数可能有的情境下不准,看下面的代码: 29 | 30 | i = 1 31 | while i != 1.5: 32 | i = i + 0.1 33 | print i 34 | 35 | # 这段代码会无限循环,因为浮点数的存储规则,只是无限接近。如0.1实际上 36 | # 存储的是0.10000000...1(截止的位置以数据类型为准),当循环到第5次的 37 | # 时候实际值是1.50000000000...4,则条件表达式True,陷入无限循环。 38 | # 39 | # 所以浮点数的比较最好能指明精度。 40 | -------------------------------------------------------------------------------- /2/Proposal14.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 14.警惕eval()的安全漏洞 4 | ############### 5 | """ 6 | 前言:eval()函数将字符串当成有效的表达式来求值并返回计算结果。 7 | 但是eval函数有安全问题。 8 | """ 9 | 10 | print "什么是eval(),看下面的例子,注意:表达式要用''或""(表示为字符串):" 11 | print eval("1+1 == 2") 12 | print eval('1 + 2') 13 | print eval("'A' + 'B'") 14 | 15 | # eval()函数是邪恶的,他可以执行"__import__("os").system("dir")"——显示当前的文件列表 16 | # 然后,入侵者还可以用类似的字符串删除你的文件,太可怕了! 17 | 18 | # 结论 19 | # 所以,如果使用对象不是信任源,应该尽量避免使用eval,在需要的使用eval的地方可以用安全性 20 | # 更好的 ast.literal_eval替代。 21 | -------------------------------------------------------------------------------- /2/Proposal15.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 15.使用enumerate()获取序列迭代的索引和值 4 | ############### 5 | """ 6 | 前言:如果要对序列进行迭代并获取序列中的元素进行处理的场景。 7 | """ 8 | # 方法1:使用range()和len()方法结合 9 | li = ['a', 'b', 'c', 'd', 'e'] 10 | for i in range(len(li)): 11 | print 'index:',i,'element:',li[i] 12 | 13 | print '------------' 14 | 15 | # 方法2:使用enumerate()获取序列迭代的索引和值 16 | li = ['a', 'b', 'c', 'd', 'e'] 17 | for i,e in enumerate(li): 18 | print 'index:',i,"element:", e 19 | 20 | # 笔记: 21 | # 使用enumerate()好,因为他代码简洁,可读性好。 22 | # 而且返回的是一个迭代器。 23 | 24 | # 注意: 25 | # 要获取迭代过程中字典的key和value,应该使用iteritems()方法。 26 | 27 | -------------------------------------------------------------------------------- /2/Proposal16.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 16.分清 == 与is的适用的场景 4 | ############### 5 | """ 6 | 前言:is的作用是用来检查队形的标示符是否一致的,也就是比较两个对象在内存中 7 | 是否拥有同一块内存空间,他并不适合用来判断两个字符串是否相等。x is y相当于 8 | id(x) == id(y) 9 | 而 == 才是用来检验两个对象的值是否相等。 10 | """ 11 | # 判断两个对象相等应该使用 == 而不是is 12 | a = 'Hi' 13 | b = 'Hi' 14 | print a is b # True 15 | print a == b # True 16 | 17 | a1 = "I am using long string for testing" 18 | b1 = "I am using long string for testing" 19 | print id(a1) 20 | print id(b1) 21 | print a1 is b1 # True 和书上的结果不一样 22 | print a1 == b1 # True 23 | 24 | str1 = "string" 25 | str2 = ''.join(['s', 't', 'r', 'i', 'n', 'g']) 26 | print str1 is str2 # Flase 27 | print str1 == str2 # True 28 | 29 | 30 | # 笔记 31 | # 32 | # python中的(字符串驻留机制) 33 | # 对于较小的字符串,为了提高系统性能会保留其值的一个副本, 34 | # 当创建新的字符串的时候直接指向该副本即可。 35 | # 而长字符串,并不会驻留,Python在内存中各自创建了对象来表示 36 | # 长字符串,这两个兑现拥有相同的内容但对象标识符却不相同。 37 | # 38 | # 39 | # 40 | 41 | 42 | -------------------------------------------------------------------------------- /2/Proposal17.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 17.考虑兼容性,尽可能使用Unicode 4 | ############### 5 | """ 6 | 前言:Python内建的字符串有两种类型:str和Unicode,因为最早的ASCII编码使用一个字节 7 | 只能表示128个字符,但是对于很多语言128个字符数远远不够,这个时候出现了多种编码格式 8 | 从而导致不同平台,不同语言之间的文本无法进行很好地转换。 9 | 要解决这个问题,必须为不同的文字分配统一的编码,Unicode,也被称为‘万国码’。 10 | """ 11 | ##### 12 | # 场景1:读取文件显示乱码 13 | 14 | filehandle = open("test.txt", 'r') # 读取测试中文文件‘test.txt’ 15 | print filehandle.read() 16 | filehandle.close() #关闭资源 17 | 18 | # 因为:文本的编码为UTF-8,但是windows系统中他被映射为GBK编码,所以在运行之后, 19 | # 两种编码并不兼容。 20 | # Unicode 为不同语言设置了唯一的二进制表表示形式(方便于相互转化) 21 | ##### 22 | 23 | # 解决办法:使用decode()和encode()方法,分别是解码和编码 24 | 25 | filehandle = open("test.txt", 'r') # 读取测试中文文件‘test.txt’ 26 | # 这里decode()方法将其他编码对应的字符串解码成Unicode, 27 | # encode()方法将Unicode编码转换为另一种编码,Unicode作为中间编码 28 | print (filehandle.read().decode("UTF-8")).encode("gbk") 29 | filehandle.close() #关闭资源 30 | 31 | 32 | ##### 33 | # 场景2:输出中文字符,抛出异常SyntaxError 34 | 35 | print '中文测试' 36 | 37 | # 因为:Python中默认的编码是ASCII编码,包含中文的字符串。当调用print输出时 38 | # 采用隐式地进行从ASCII到系统默认编码的转换,中文字符并不是ASCII字符,此时 39 | # 源文件又未指定其他编码方式,这时便会抛出SyntaxError异常 40 | ##### 41 | # 解决办法:在源文件中进行编码声明, 42 | # 如:#coding=utf-8 43 | 44 | print '中文测试' 45 | 46 | 47 | ##### 48 | # 场景3:普通字符串和Unicode进行字符串连接时抛出UnicodeDecodeError异常 49 | 50 | print '中文测试' + u'Chinese Test' #抛出异常 51 | 52 | # 因为:当两种类型的字符串连接的时候,Python将左边的中文字符串转换为 53 | # Unicode再与右边的Unicode字符串连接,这时将‘中文测试’字符串转换为Unicode 54 | # 使用系统默认的ASCII编码对字符串进行解码,但是其中‘中’字对应的值为214, 55 | # 当编码值在0~127的时候Unicode和ASCII是兼容的,但是大于128的时候,ASCII编码 56 | # 不能正确处理这种情况,则抛出异常 57 | ##### 58 | # 解决办法:把中文字符解码成gbk编码 59 | print '中文测试'.decode('gbk') + u'Chinese Test' 60 | 61 | 62 | # 笔记 63 | # 对于中文字符,为了做到不同系统之间的兼容,建议使用Unicode方式表示。 64 | # Python2.6之后可以通过import unicode_literals自动将定义的普通字符 65 | # 识别为Unicode字符串,这样字符串的行为将和Python3中保持一致。 66 | 67 | # 形式如下: 68 | 69 | #from __future__ import unicode_literals 70 | s = '中文测试' 71 | print s 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /2/Proposal18.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 18.构建合理的包层次来管理module 4 | ############### 5 | """ 6 | 前言:本质上每一个Python文件都是一个模块,使用模块可以增强代码的可维护性和可重用性。 7 | 在大型项目中,我们需要合理地组织项目的层次来管理模块,这就是包(Package)。 8 | """ 9 | 10 | # 笔记 11 | # 12 | # 简单的说包就是目录,与目录不同的是,它除了包含模块以外,还包含一个__init__.py文件, 13 | # 它的作用是区别包和不同目录。 14 | # 同时他允许嵌套。 15 | # 1.直接导入一个包,调用时Package.a 16 | #import Package 17 | # 18 | # 2.导入子模块或者子包,可以直接使用Module1.name 19 | #from Package import Module1 20 | # 21 | # 包的使用能够带来以下便利: 22 | # 1.合理组织代码,有利于维护和使用:使用项目结构更为完善和合理,从而增强代码的可维护性和实用性 23 | # 2.能够有效地避免名称空间冲突:使用from...import访问是不需要加入包名;如果模块包含的属性或者方法 24 | # 存在同名冲突,使用import modle 可以有效地避免名称冲突。 25 | -------------------------------------------------------------------------------- /2/Proposal8.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 8利用assert语句来发现问题 4 | ############### 5 | def foo(x): 6 | assert x,"提示信息" 7 | 8 | foo(0) 9 | 10 | # 笔记 11 | # 断言是被设计用来捕获用户定义的约束的,而不是用来不或程序本身错误的 12 | # 使用时请注意一下几点: 13 | # 1.不要乱用,应该用在正常逻辑不可达到的地方或正常情况下作为真的场合 14 | # 2.如果Python本身的异常能够处理就不要在使用断言,例如:如果传入的参数 15 | # 一个为字符串,另外一个为数字或者列表,本身就会抛出TypeError 16 | def stradd(x,y): 17 | assert isinstance(x,basestring) # 多次一举 18 | assert isinstance(y,basestring) # 注释掉这两行,抛出TypeError 19 | return x + y 20 | 21 | stradd(1, 'test') 22 | # 3.不要用断言来检查用户的输入。较好的做法是使用条件判断,并在不符合 23 | # 条件时输出错误提示。 24 | # 4.在函数调用后,当需要确认返回值是否合理时使用断言。 25 | # 5.当条件是业务逻辑继续下去的先决条件时可以使用断言。 26 | -------------------------------------------------------------------------------- /2/Proposal9.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ################ 3 | # 9数据交换值的时候不推荐使用中间变量 4 | ############### 5 | from timeit import Timer 6 | 7 | t1 = Timer('temp = x;x = y;y = temp', 'x = 2;y = 3').timeit() 8 | t2 = Timer('x, y = y, x', 'x = 2;y = 3').timeit() 9 | 10 | print "使用中间值,用时:", t1 11 | print "不使用中间值,用时:", t2 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python_skill 2 |
4 |
25 |