分享书籍[writing idiomatic python ebook]

时间:2023-01-29 11:40:55

你是不是总是觉得学了python好久,蓦然回首,总是感觉写的代码不是那么有pythonic的味道。看看别人的代码(django,webpy),再看看自己的代码,觉得就是一java-python的混合体。鉴于这种问题,我准备要多学习别人的一些技术和方式,这不,在网上看到一本不错的书:[writing idiomatic python ebook] 。告诉怎么写出python风格的代码。本来想共享到网盘的,但是一想,这样不好吧,人家的书是挂在上面付费卖的,也不贵,10刀。所以就不共享了。这里把里面的一些注意点以笔记的形式分享出来一起学习。

ps:我今天发现在163网易阅读里有这本书,提供下链接:http://yuedu.163.com/source/cl_dc23b96c2df84533957ffb1089e90604_4

在if语句中用链式比较使之更简明

x = 5
if x > 1 and x < 6:
print 'python'

改成:

if 1 < x < 6:
print 'python'

不要在if语句后面直接写代码,而是换行

x = True
if x:print 'python'
print 'is great!'

改成:

x = True
if x:
print 'python'
print 'is great!'

  

在条件判断时,应该避免直接和True,False,None进行比较(==)

比如我们判断一个集合为空是,会这样写:

l = []
if l == []:
print 'l is empty list'

改成:

l = []
if not l:
print 'l is empty list'

其实在if语条的条件判断时,我们一般的语境上下文还是很明确,如对象是否为None,是否条件为True,或者集合是否为空,字典是否为空。python支持直接在if后台跟着这些对象,自动为根据语境转换为相应的布尔值(True或False)。 满足如下的情况,都会认为是False:

  1. None
  2. False
  3. 为0的数值型实例(number)
  4. 空的序列,如list, tuple
  5. 空的字典,如dict
  6. 在自定义的类中定义了__len__返回0 ,或者定义了__nonzero__返回False

但是有些情况还是不同的,不能适用于这个规则。看下面一个实例:

def getCurrentPositon(position=None):
if not position:
print 'you must set you current position!' getCurrentPositon(0)

方法的作用是得到根据传入的位置做相应的工作。如果传入参数0应该也是合理值,即在坐标原点位置。但是方法还是会打印'you must set you current position!'。 因为0值被条件判断为False。所以应该改成如下 :

def getCurrentPositon(position=None):
if position is None:
print 'you must set you current position!' getCurrentPositon(0)

显示的比较是否为None,而不依赖内建的布尔转换。注意这里是用 is 操作符没有用 == 比较符。因为None对象在python中是单实例的,而is就是直接比较两个对象是否一样(可以理解占用同一条内存)

用if,else替换三元(ternary)运算操作符

flag = 2

if flag == 1:
displayValue = 'man'
elif flag == 2:
displayValue = 'woman'

改成:

displayValue = 'man' if flag == 1 else 'woman'

用enumerate函数代替for循环中的index变量访问

my_container = ['lily', 'lucy', 'tom']
index = 0
for element in my_container:
print '{} {}'.format(index, element)
index += 1

改成:

for index, element in enumerate(my_container):
print '%d %s' % (index, element)

当for循环体执行完后,可以用else去执行相关的动作

如这样的场景:遍历所有人的年龄信息,决断当前所有人是不是都是成年人,假如以大于等于20岁划分:

all_person_age = [21, 22, 23, 30]

is_all_adult = True
for age in all_person_age:
if age <= 20:
is_all_adult = False
break if is_all_adult:
print 'Tha all are audlt!'

我们这里加了一个 is_all_adult 的标志变量,在循环体中当有年龄小于20岁的人时,把该变量重新置值, 并跳出循环体。我们可以改成 for ... else 的句式,这样可以省略定义一个标志变量:

all_person_age = [21, 22, 23, 32]

for age in all_person_age:
if age <= 20:
break
else:
print 'Tha all are audlt!'

for...else...的用法就是当for中途退出循环时(没有遍历所有的集合元素)时就不执行else里的语句,反之则执行。

避免用可变的对象(mutable)作为函数参数中的默认初始化值

def function(l = []):
l.append(1)
return l print function()
print function()
print function()

将会打印:

[1]
[1, 1]
[1, 1, 1]
[Finished in 0.0s]

这是因为参数的默认初始值只有在定义的时候执行一次,即是单实例的。以后的每一次调用都会用这个对象。改成:

def function(l = None):
if l is None:
l = []
l.append(1)
return l

尽量少定义一些只是用于存储返回值的变量

def all_equal(a, b, c):
result = False
if a == b == c:
result = True
return result

改成:

def all_equal(a, b, c):
return a == b == c

试着把函数当成对象实例来用,无论是参数传入还是返回值

def print_addition_table():
for x in range(1, 3):
for y in range(1, 3):
print(str(x + y) + '\n') def print_subtraction_table():
for x in range(1, 3):
for y in range(1, 3):
print(str(x - y) + '\n') def print_multiplication_table():
for x in range(1, 3):
for y in range(1, 3):
print(str(x * y) + '\n') def print_division_table():
for x in range(1, 3):
for y in range(1, 3):
print(str(x / y) + '\n') print_addition_table()
print_subtraction_table()
print_multiplication_table()
print_division_table()

像上面的定义的四个函数,基本结构一样,只是里面进行的运算不同而也(+, -, *, /),我们可以把运算的函数直接作为参数传递进去即可:

import operator as op

def print_table(operator):
for x in range(1, 3):
for y in range(1, 3):
print(str(operator(x, y)) + '\n') for operator in (op.add, op.sub, op.mul, op.div):
print_table(operator)

在python世界里,一切都是对象,Function也是

多用EAFP,少用LBYL

EAFP:easier to ask forgiveness than permission

LBYL:look before you leap

EAFP可以理解成一切按正常的逻辑编码,不用管可能出现的错误,等出了错误再说;而LBYL就是尽可能每写一行代码,都要提前考虑下当前的前置条件是否成立;

LBYL代码风格:

def getPersonInfo(person):
if person == None:
print 'person must be not null!'
print person.info

EAFP代码风格:

def getPersonInfo(person):
    try:
print person.info
except NameError:
print 'person must be not null!'

其实用EAFP风格的代码最大的好处是代码逻辑清晰,而LBYL会导致本来两句话说清楚的事,往往因为穿插了很多条件检查的语句使代码逻辑变得混乱。

不要一根筋似的看到异常就catch并吃掉(swallowing)

如下定义一个方法,请求url并返回响应:

import requests
def get_json_response(url):
try:
r = requests.get(url)
return r.json()
except:
print('Oops, something went wrong!')
return None

如果这个函数给第三方调用,万一出了什么问题,用户只会得到一个something went wrong提示,而只能猜出错的原因,是GFW的问题呢,还是url地址格式错误呢。改成如下:

import requests
def get_json_response(url):
return requests.get(url).json()

把出错的处理权力交给调用方。

分享书籍[writing idiomatic python ebook]的更多相关文章

  1. 分享书籍&lbrack;writing idiomatic python ebook&rsqb; 二

    对多个变量设置相同的值时,用连等号一起赋值 x = 10 y = 10 z = 10 改成: x = y = z = 10 交换变量值时,可以避免定义新的临时变量 x = 10 y = 5 temp ...

  2. 《Writing Idiomatic Python》前两部分的中文翻译

    汇总了一下这本小书前两部分的内容: 翻译<Writing Idiomatic Python>(一):if语句.for循环 翻译<Writing Idiomatic Python&gt ...

  3. 翻译《Writing Idiomatic Python》(五):类、上下文管理器、生成器

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...

  4. 翻译《Writing Idiomatic Python》(四):字典、集合、元组

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...

  5. 翻译《Writing Idiomatic Python》(三):变量、字符串、列表

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...

  6. 翻译《Writing Idiomatic Python》(一):if语句、for循环

    开篇废话 这是在美国Amazon上评价很不错的一本书,其实严格来说这可能不算书,而是一本小册子.就像书名一样,里面的内容主要是用一些例子讲述地道的Python的代码是怎样写的.书中把很多例子用不良风格 ...

  7. 翻译《Writing Idiomatic Python》(二):函数、异常

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...

  8. Python——Code Like a Pythonista&colon; Idiomatic Python

    Code Like a Pythonista: Idiomatic Python 如果你有C++基础,那学习另一门语言会相对容易.因为C++即面向过程,又面向对象.它很底层,能像C一样访问机器:它也很 ...

  9. python书籍推荐:python编码推荐(高清完整pdf)

    目录INF-qa Python 编码规范................................................................................ ...

随机推荐

  1. Comet:基于 HTTP 长连接的&OpenCurlyDoubleQuote;服务器推”技术解析

    原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...

  2. JVM中显示锁基础AbstractQueuedSynchronizer

    在研究AbstractQueuedSynchronizer的时候我是以ReentrantLock入手的.所以理所当然会设计到一些ReentrantLock的方法.因为网上已经有很多关于AQS的文章了, ...

  3. arcgis api for javascript 3&period;16开发(一)

    原来一直都在用Flex开发arcgis的地图接口,用的时间很长,用的习惯也顺手,可Flex这个开发工具已经基本要淘汰了,并且地图借助flash的方式加载在浏览器里已经不能适应webgis的快速开发需求 ...

  4. bash 的漏洞,你们中招了吗?

    http://threatpost.com/major-bash-vulnerability-affects-linux-unix-mac-os-x 检测: $ env x='(){:;}; echo ...

  5. datagridview,textbox,combobox的数据绑定,数据赋值,picturebox的用法

    一:datagridview数据绑定 二:textbox的数据绑定(datetimepicker) 总结: 最好还是写成双向绑定那种,不要再写出发事件了,只要在给textbox赋值就能重新绑定了,不然 ...

  6. Round Numbers

    转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1301472836 大致题意: 输入两个十进制正整数a和b,求闭区间 [a ,b] 内有多少 ...

  7. UNIX基础--用户和基本账户管理

    账户类型 系统账户 系统账户运行服务. 系统用户是那些要使用诸如DNS. 邮件, web等服务的用户. 使用帐户的原因就是安全: 如果所有的用户都由超级用户来运行, 那它们就可以不受约束地做任何事情. ...

  8. React-理解高阶组件

    高阶组件:定义一个函数,传入一个组件,返回另外一个组件,另外一个组件包裹了传入的组件. 分类:属性代理高阶组件,反向继承高阶组件. 作用:代码复用,渲染节时. 高阶函数例子: function hel ...

  9. zjoi 网络

    题解: 很显然会发现对于每种颜色分开处理这是一颗树 然后就是裸的lct 有个坑就是判断操作1 可能颜色改成跟原先一样的 代码: #include <bits/stdc++.h> using ...

  10. 30&period; Substring with Concatenation of All Words

    题目: You are given a string, s, and a list of words, words, that are all of the same length. Find all ...