python 反模式
不使用 pythonic 的循环:
l = [1,2,3]
#Bad
for i in range(0,len(list)):
le = l[i]
print(i,le)
#Good
for i,le in enumerate(l):
print(i,le)
函数调用返回一个以上的变量类型
#Bad
def filter_for_foo(l):
r = [e for e in l if e.find("foo") != -1]
if not check_some_critical_condition(r):
return None
return r
res = filter_for_foo(["bar","foo","faz"])
if res is not None:
#continue processing
pass
#Good
def filter_for_foo(l):
r = [e for e in l if e.find("foo") != -1]
if not check_some_critical_condition(r):
raise SomeException("critical condition unmet!")
return r
try:
res = filter_for_foo(["bar","foo","faz"])
#continue processing
except SomeException:
#handle exception
循环永不终止
#example:
i = 0
while i < 10:
do_something()
#we forget to increment i
不使用 .iteritems() 遍历 dict 的键/值对.
#Bad
d = {'foo' : 1,'bar' : 2}
for key in d:
value = d[key]
print("%s = %d" % (key,value))
#Good
for key,value in d.iteritems():
print("%s = %d" % (key,value))
不使用 zip() 遍历一对列表
#Bad
l1 = [1,2,3]
l2 = [4,5,6]
for i in range(l1):
l1v = l1[i]
l2v = l2[i]
print(l1v,l2v)
#Good
for l1v,l2v in zip(l1,l2):
print(l1v,l2v)
Using "key in list" to check if a key is contained in a list.
This is not an error but inefficient, since the list search is O(n). If possible, a set or dictionary
should be used instead.
Note: Since the conversion of the list to a set is an O(n) operation, it should ideally be done only once when generating the list.
#Bad:
l = [1,2,3,4]
if 3 in l:
pass
#Good
s = set(l)
if 3 in s:
pass
在循环之后,不使用 'else'.
#Bad
found = False
l = [1,2,3]
for i in l:
if i == 4:
found = True
break
if not found:
#not found...
pass
#Good
for i in l:
if i == 4:
break
else:
#not found...
对于dict,不使用.setdefault()设置初始值
#Bad
d = {}
if not 'foo' in d:
d['foo'] = []
d['foo'].append('bar')
#Good
d = {}
foo = d.setdefault('foo',[])
foo.append(bar)
对于dict,不使用.get()返回缺省值
#Bad
d = {'foo' : 'bar'}
foo = 'default'
if 'foo' in d:
foo = d['foo']
#Good
foo = d.get('foo','default')
使用map/filter而不是列表解析
#Bad:
values = [1,2,3]
doubled_values = map(lambda x:x*2,values)
#Good
doubled_values = [x*2 for x in values]
#Bad
filtered_values = filter(lambda x:True if x < 2 else False,values)
#Good
filtered_values = [x for x in values if x < 2]
不使用defaultdict
#Bad
d = {}
if not 'count' in d:
d['count'] = 0
d['count']+=1
#Good
from collections import defaultdict
d = defaultdict(lambda :0)
d['count']+=1
从一个函数中返回多个值时,不使用命名元组(namedtuple)
命名元组可以用于任何正常元组使用的地方,但可以通过name访问value,而不是索引。这使得代码更详细、更容易阅读。
#Bad
def foo():
#....
return -1,"not found"
status_code,message = foo()
print(status_code,message)
#Good
from collections import namedtuple
def foo():
#...
return_args = namedtuple('return_args',['status_code','message'])
return return_args(-1,"not found")
ra = foo()
print(ra.status_code,ra.message)
不使用序列的显式解包
支持解包的序列有:list, tuple, dict
#Bad
l = [1,"foo","bar"]
l0 = l[0]
l1 = l[1]
l2 = l[2]
#Good
l0,l1,l2 = l
不使用解包一次更新多个值
#Bad
x = 1
y = 2
_t = x
x = y+2
y = x-4
#Good
x = 1
y = 2
x,y = y+2,x-4
不使用'with'打开文件
#Bad
f = open("file.txt","r")
content = f.read()
f.close()
#Good
with open("file.txt","r") as input_file:
content = f.read()
要求许可而不是宽恕
#Bad
import os
if os.path.exists("file.txt"):
os.unlink("file.txt")
#Good
import os
try:
os.unlink("file.txt")
except OSError:
pass
不使用字典解析
#Bad
l = [1,2,3]
d = dict([(n,n*2) for n in l])
#Good
d = {n : n*2 for n in l}
使用字符串连接,而不是格式化
#Bad
n_errors = 10
s = "there were "+str(n_errors)+" errors."
#Good
s = "there were %d errors." % n_errors
变量名包含类型信息(匈牙利命名)
#Bad
intN = 4
strFoo = "bar"
#Good
n = 4
foo = "bar"
实现java风格的getter和setter方法,而不是使用属性。
#Bad
class Foo(object):
def __init__(a):
self._a = a
def get_a(self):
return a
def set_a(self,value):
self._a = value
#Good
class Foo(object):
def __init__(a):
self._a = a
@property
def a(self):
return self._a
@a.setter
def a(self,value):
self._a = value
#Bad
def calculate_with_operator(operator, a, b):
if operator == '+':
return a+b
elif operator == '-':
return a-b
elif operator == '/':
return a/b
elif operator == '*':
return a*b
#Good
def calculate_with_operator(operator, a, b):
possible_operators = {
'+': lambda a,b: a+b,
'-': lambda a,b: a-b,
'*': lambda a,b: a*b,
'/': lambda a,b: a/b
}
return possible_operators[operator](a,b)
#Bad
class DateUtil:
@staticmethod
def from_weekday_to_string(weekday):
nameds_weekdays = {
0: 'Monday',
5: 'Friday'
}
return nameds_weekdays[weekday]
#Good
def from_weekday_to_string(weekday):
nameds_weekdays = {
0: 'Monday',
5: 'Friday'
}
return nameds_weekdays[weekday]
python 反模式的更多相关文章
- Python编程中的反模式
Python是时下最热门的编程语言之一了.简洁而富有表达力的语法,两三行代码往往就能解决十来行C代码才能解决的问题:丰富的标准库和第三方库,大大节约了开发时间,使它成为那些对性能没有严苛要求的开发任务 ...
- ORM 是一种讨厌的反模式
本文由码农网 – 孙腾浩原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! (“Too Long; Didn’t Read.”太长不想看,可以看这段摘要 )ORM是一种讨厌的反模式,违背 ...
- 《SQL 反模式》 学习笔记
第一章 引言 GoF 所著的的<设计模式>,在软件领域引入了"设计模式"(design pattern)的概念. 而后,Andrew Koenig 在 1995 年造了 ...
- 重构24-Remove Arrowhead Antipattern(去掉箭头反模式)
基于c2的wiki条目.Los Techies的Chris Missal同样也些了一篇关于反模式的post. 简单地说,当你使用大量的嵌套条件判断时,形成了箭头型的代码,这就是箭头反模式(arrow ...
- Apache Hadoop最佳实践和反模式
摘要:本文介绍了在Apache Hadoop上运行应用程序的最佳实践,实际上,我们引入了网格模式(Grid Pattern)的概念,它和设计模式类似,它代表运行在网格(Grid)上的应用程序的可复用解 ...
- 开发反模式 - SQL注入
一.目标:编写SQL动态查询 SQL常常和程序代码一起使用.我们通常所说的SQL动态查询,是指将程序中的变量和基本SQL语句拼接成一个完整的查询语句. string sql = SELECT * FR ...
- 开发反模式(GUID) - 伪键洁癖
一.目标:整理数据 有的人有强迫症,他们会为一系列数据的断档而抓狂. 一方面,Id为3这一行确实发生过一些事情,为什么这个查询不返回Id为3的这一行?这条记录数据丢失了吗?那个Column到底是什么? ...
- 查询反模式 - 正视NULL值
一.提出问题 不可避免地,我们都数据库总有一些字段是没有值的.不管是插入一个不完整的行,还是有些列可以合法地拥有一些无效值.SQL 支持一个特殊的空值,就是NULL. 在很多时候,NULL值导致我们的 ...
- Python教程(1.2)——Python交互模式
上一节已经说过,安装完Python,在命令行输入"python"之后,如果成功,会得到类似于下面的窗口: 可以看到,结尾有3个>符号(>>>).>&g ...
随机推荐
- iOS开发笔记3:XML/JSON数据解析
这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...
- iOS UIButton添加圆角,添加边框
//准备工作 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(,, ...
- GET/POST请求的使用《极客学院 --AFNetworking 2.x 网络解析详解--2》学习笔记
AFNetworking是开源代码排名第一的开源库. GET请求的请求正文 一般都是明文显示的,携带的数据量小. POST用于处理复杂的业务,并不用明文的请求,其实POST请求可以携带更多的参数,只 ...
- PHP session 跨子域问题
今天,做项目时候遇到个问题.之前做东西的时候session一般就直接存在数据库中这样就能解决跨域 不仅仅是跨子域,但是今天遇到这个问题是,自己要在别人现有的东西上面做修改.由于仅仅是子域 当时就行肯定 ...
- ORACLE 创建与使用视图
一.what(什么是视图?) 1.视图是一种数据库对象,是从一个或者多个数据表或视图中导出的虚表,视图所对应的数据并不真正地存储在视图中,而是存储在所引用的数据表中,视图的结构和数据是对数据表进行查询 ...
- 第八章 了解tempdb数据库
1.一个sqlserver数据库实例上只能有一个tempdb数据库,这个实例上所有的用户都共享这个数据库.2.tempdb数据库在每次sqlserver重启后都会重新创建,所以数据会丢失.3.因为te ...
- PS网页设计教程XXX——在PS中创建一个漫画书主题网页布局
作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,“熟读唐诗三百首,不会作诗也会吟”. 本系列的教程来源于网上的PS教程,都是国外的,全英文的.本人尝试 ...
- 如何正大光明的使用 google 进行搜索
对于程序猿来说,不能使用google,是一大痛所在,今天在使用 百度网盘 搜索时,突然发现 ,他能同时使用 baidu和 google进行搜索,于是想到了这个正大光明的使用google 的方法,不需要 ...
- Linux Purify命令
一.简介 在C/C++的软件开发中,没有任何一种工具可以让你的应用程序避免引入内存问题,但是我们可以使用诸如Purify这样的工具对已经做好了的程序进行内存问题的检查.Purify的强大之处是可以找到 ...
- OFFICE2013实现选中单元格所在行、列高亮显示
在你要实现此功能的工作表标签右击,在弹出的菜单中选择编辑代码,然后输入下面代码保存即可! 如没有出现效果,则可能是禁用了宏的关系.所以要在安全选项中启用宏选项. Private Sub Workshe ...