本系列來自《編寫高品質代碼 改善python程式的91個建議》的讀書筆記整理。python程式設計規範系列--建議08~18
本系列來自《編寫高品質代碼 改善python程式的91個建議》的讀書筆記整理。
本章主要内容
建議8:利用assert語句來發現問題
建議9:資料交換值時不推薦使用中間交換變量
建議10:充分利用Lazy evaluation的特性
建議11:了解枚舉替代實作的缺陷
建議12:不推薦使用type來進行類型檢查
建議13:盡量轉換為浮點類型再做除法
建議14:警惕eval()的安全漏洞
建議15:使用enumerate()擷取序列疊代的索引和值
建議16:厘清==與is的适用場景
建議17:考慮相容性,盡可能使用Unicod
建議18:建構合理的包層次來管理module
1)__debug__的值預設為True,且隻讀,無法修改(py2.7)。
2)斷言是有代價的,對性能産生一定影響。禁用斷言的方法是在運作腳本的時候加上-O标記(不優化位元組碼,而是忽略與斷言相關的語句)。
使用斷言注意點:
1)不要濫用,這是使用斷言的最基本的原則;
2)如果Python本身的異常能夠處理就不要再使用斷言;
3)不要使用斷言來檢查使用者的輸入;
4)在函數調用後,當需要确認傳回值是否合理時可以使用斷言;
5)當條件時業務邏輯繼續下去的先決條件時,可以使用斷言。
1 >>> from timeit import Timer
2 >>> Timer('temp=x;x=y;y=temp','x=2;y=3').timeit()
3 0.03472399711608887
4 >>> Timer('x,y=y,x','x=2;y=3').timeit()
5 0.031581878662109375
Lazy evaluation常被譯作“延時計算”或“惰性計算”,指的是僅僅在真正需要執行計算的時候才計算表達式的值。典型例子:生成器表達式。
1)避免不必要的計算,帶來性能上的提升;
2)節省空間,使用無限循環的資料結構成為可能。
1)替代方法:使用類屬性;借助函數;使用collections.namedtuple.
1 >>> from collections import namedtuple
2 >>> Seasons=namedtuple('Seasons','Spring Summer Autumn Winter')._make(xrange(4))
3 >>> print Seasons
4 Seasons(Spring=0, Summer=1, Autumn=2, Winter=3)
5 >>> print Seasons.Autumn
6 2
2)替代缺陷:允許枚舉值重複;支援無意義的操作.
1 >>> Seasons._replace(Spring=2) # 不合理
2 Seasons(Spring=2, Summer=1, Autumn=2, Winter=3)
3 >>> Seasons.Summer+Seasons.Autumn == Seasons.Winter # 無意義
4 True
3)py2.7的替代方案(py3.4後引入Enum類型):flufl.enum
1 from flufl.enum import Enum
2
3
4 class Seasons(Enum):
5 Spring = "Spring"
6 Summer = 2
7 Autumn = 3
8 Winter = 4
9
10 Seasons = Enum('Seasons', 'Spring Summer Autumn Winter')
11 print Seasons
12 print Seasons.Summer.value
1)基于内建類型擴充的使用者自定義類型,type函數并不能準确傳回結果;
2)在舊式類中,所有類的執行個體的type值都相等。
3)可以用isinstance()函數檢查。
當涉及除法運算的時候盡量先将操作數轉換成浮點類型再做運算。
浮點數不精确性導緻的無限循環:
1 >>> i=1
2 >>> while i!=1.5:
3 ... i=i+0.1
4 ... print i
1 # -*-coding:UTF-8 -*-
2
3 import sys
4 from math import *
5
6
7 def ExpCalcBot(string):
8 try:
9 print 'Your answer is', eval(string)
10 except NameError:
11 print "The expression you enter is not valid."
12
13
14 while True:
15 print 'Please enter a number or operation. Enter e to complete. '
16
17 inputStr = raw_input()
18 if inputStr == 'e':
19 sys.exit()
20 elif repr(inputStr) != ' ':
21 ExpCalcBot(inputStr)
輸入:__import__("os").system("dir") 顯示目前目錄下的所有檔案.
__import__("os").system("del */Q") 删除目前目錄下的所有檔案.
是以,在實際應用過程中國呢如果使用對象不是信任源,應該盡量避免使用eval,在需要使用eval的地方可以用安全性更好的ast.literal_eval替代。
注意,在擷取疊代過程中字典的key和value,應該使用如下iteritems()方法。
1 >>> person={'name': 'Josn', 'age': 19, 'hobby': 'football'}
2 >>> for k,v in person.iteritems():
3 ... print k, ":", v
1 >>> a="Hi"
2 >>> b="Hi"
3 >>> a is b
4 True
5 >>> a==b
6 True
7 >>> a1 ="I am using long string for testing" # 注意區分
8 >>> b1 ="I am using long string for testing"
9 >>> a1 is b1
10 False
11 >>> a1==b1
12 True

is:表示的是對象辨別符,檢查對象的辨別符是否一緻,也就是比較兩個對象在記憶體中是否擁有同一塊記憶體空間;
==:表示的是值相等,用來判斷兩個對象的值是否相等,可以被重載。
字元串駐留(string interning)機制:對于較小的字元串,為了提高系統性能會保留其值的一個副本,當建立新的字元串時直接指向該副本即可。
建議17:考慮相容性,盡可能使用Unicode
python内建的字元串有兩種類型:str和Unicode,共同祖先為basestring。
windows本地預設編碼是CP936。
解碼:str.decode([編碼參數[,錯誤處理]])
編碼:str.encode([編碼參數[,錯誤處理]])
錯誤處理參數有3種方式:
(1)strict:預設值,抛出UnicodeError異常;
(2)ignore:忽略不可轉換的字元;
(3)replace:将不可轉換字元用?代替。
有些軟體在儲存UTF-8編碼時,會在檔案最開始地方插入不可見的BOM,可以利用codecs解決。
1 import codecs
2
3
4 content = open('manage.py', 'r').read()
5
6 if content[:3] == codecs.BOM_UTF8:
7 content = content[:3]
8
9 print content.decode("utf-8")
編碼聲明的三種方式:
1 # coding=<encoding name> #方式一
2 #!/usr/bin/env python
3
4 # -*- coding:<encoding name> -*- #方式二
5
6 #!/usr/bin/env python
7 # vim:set fileencoding=<encoding name> #方式三
包中__init__.py檔案的作用:1)使包和普通目錄區分;
2)在該檔案中聲明子產品級别的import語句進而使其變成包級别可見;
3)通過該檔案中定義__all__變量,控制需要導入的子包或者子產品。
使用包的好處:
1)合理組織代碼,便于維護和使用;
2)能夠有效地避免名稱空間沖突。
PS:如果你覺得文章對你有所幫助,别忘了推薦或者分享,因為有你的支援,才是我續寫下篇的動力和源泉!
作者:
zhangbc
出處:
http://www.cnblogs.com/zhangbc/
格言:
我願意做一隻蝸牛,慢慢地向前爬,不退縮,不洩氣,做好自己,立足當下,展望未來!
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
posted @
2019-01-18 21:44
天堂的鴿子
閱讀(548)
評論(2)
編輯
收藏
舉報