[effective python]改善python代码的91个建议-chapter2

编程惯例
1 assert
x = 1
y = 2
assert x == y, "Not equals"


python -O .\asserttest.py # 加上-O 参数禁止断言

## 建议9 数据交换值不推荐使用中间变量
x = 1
y = 2
y, x = x, y
print x
print y


遇到表达式赋值表达式的右边操作数优先于左边的操作数计算,例如

expr3, expr4 = expr1, expr2
的执行顺序:
expr1->expr2->expr3->expr4

使用dis模块进行代码层次的性能剖析
http://blog.csdn.net/handsomekang/article/details/41479597

## 建议10 充分利用lasy evaluation惰性计算

def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a+b

from itertools import islice
print list(islice(fib(), 5))

## 建议11 理解枚舉替代實現的缺陷

class Seasons:
Spring = 0
Summer = 1
Autumn = 2
Winter = 3


可以用以下簡化
class Seasons:
Spring, Summer, Autumn, Winter = range(4)


## 建議12 不建議使用type來進行類型檢查
基於內建類型擴展的用戶自定義類型,type函數並不能準確返回結果

可以用isinstance(n, int) 來判斷

## 建議13 盡量轉換為浮點類型後再做除法
gpa = ((4*96 + 3*85 + 5*98 + 2*70) * 4) / ((4+3+5+2) * 100)
print gpa


輸出3
gpa = float(((4*96 + 3*85 + 5*98 + 2*70) * 4)) / float(((4+3+5+2) * 100))

轉換成float類型後,輸出3.62571428571 python3已經不存在這個問題了

也可以通過
from __future__ import division
gpa = ((4*96 + 3*85 + 5*98 + 2*70) * 4) / ((4+3+5+2) * 100)
print gpa


輸出也是3.62571428571

i = 1
while i != 1.5:
i = i + 0.1
print i


以上代碼並不會如願輸出到1.5 就停止。而是會不斷循環。
因為0.1轉換成二進制形式,1001會無限循環,i != 1.5 永遠為true

如果計算對精度要求高,可以使用Decimal來進行處理或將浮點數盡量擴大為整數,計算完畢後再傳回去

建議14 警惕eval()的安全漏洞

建議15 使用enumerate()獲取序列迭代的索引和值


第一種寫法
li = ['a', 'b', 'c', 'd', 'e']
index = 0
for i in li:
print "index:", index, "element:", i
index+=1


第二種寫法
li = ['a', 'b', 'c', 'd', 'e']
for i in range(len(li)):
print "index:", i , "element:", li[i]


第三種寫法
li = ['a', 'b', 'c', 'd', 'e']
index = 0
while index < len(li):
print "index:", index , "element:", li[index]
index += 1


第四種寫法
li = ['a', 'b', 'c', 'd', 'e']
for i, e in zip(range(len(li)), li):
print "index:", i , "element:", e



第五種寫法(推薦)
li = ['a', 'b', 'c', 'd', 'e']
for i, e in enumerate(li):
print "index:", i , "element:", e



enumerate()的內部實現
def enumerate(sequence, start=0):
n = start
for elem in sequence:
yield n, e
lem
n += 1

enumerate()不適合字典{},字典建議用iteritems()
persioninfo = {"name":"Jon", 'age': '20', 'hobby':'football'}
for k, v in persioninfo.iteritems():
print k, ":", v

## 建議16 分清==與is的適用場景

通過id()函數來看這些變量在內存中的具體存儲空間

is: object identity 對象標識符,比較是否同一個內存空間
==: equal

## 建議17 考慮兼容性,盡量使用unicode
# coding=utf-8
s = "中文測試" + u"Chinese Test"
print s

s會報錯
解決方法1:
s = "中文測試".decode("gbk") + u"Chinese Test"


解決方法2:
s = "中文測試" + u"Chinese Test".encode("utf-8")

解決方法3:(推薦) 自動將定義的普通字符識別為unicode字符串
from __future__ import unicode_literals
s = "中文測試" + u"Chinese Test"


建議18 構建合理的包層次來管理module

__init__.py 的作用:
1 使包和普通目录区分
2 在该文件中申明模块级别的import语句,从而使其变成包级别可见
如果__init__.py文件为空,当意图使用
from Package import * 将包package中所有的模块导入当前命名空间时并不能使的导入的模块生效
以*导入时,package内的module是受__init__.py限制的。

__all__ = ['module_12', 'module_13']


http://www.cnpythoner.com/post/2.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值