命令行
python -version
程序内
import sysprint(sys.version_info)print(sys.version)
2. 遵循PEP8的风格在线文档 http://www.python.org/dev/peps/pep-0008/规则例子space空格缩进使用spaces 代替 tabs每一级的缩进使用四个spaces每行79个字符或者更少长表达式换行也要缩进四个空格函数与函数、类与类之间 必须被两个空行分开类的函数需要被一行空行分开不要在列表索引、函数调用或关键字参数赋值周围放空格在变量赋值的前后放且仅放一个空格命名函数、变量和属性应采用小写下划线格式私有实例属性应该采用__double_leading_下划线格式类和异常应该大写模块级常量应该是ALL_CAPS格式类中的实例方法应该使用self作为第一个参数的名称类方法应该使用cls作为第一个参数的名称表达式和语句使用内联否定(Python Enhancement Proposal #8
if a is not b
)代替肯定的否定(if not a is b
)不要通过检查长度来检查空值(如[]或")(if len(someList) == 0
), 而使用if not someList
同上条,非空值使用 if someList
避免单行的 if for whileimport
总放在最前面在导入模块时,总是使用模块的绝对名称如果必须进行相对导入,则使用显式语法from . import foo
导入应该按以下顺序分节:标准库模块,第三方模块,你自己的模块。3. 知道 bytes、str和unicode之间的差别字符串的表达版本 | 表达方法 |
---|---|
python2 | unicode 和 str |
python3 | bytes 和 str |
str
实例 和python2 中的 unicode
实例没有相关的二进制编码 Unicode–>二进制:encode二进制–>Unicode: decode 确保类型返回一致python3# 始终返回strdef to_str(bytes_or_str): return bytes_or_str.decode('utf-8') if isinstance(bytes_or_str,bytes) else bytes_or_str# 始终返回bytesdef to_bytes(bytes_or_str): return bytes_or_str.encode('utf-8') if isinstance(bytes_or_str,str) else bytes_or_str
4. 写辅助函数而不是复杂函数表达式可读性
在python中很容易写一个表达式完成功能。例如解析URL
from urllib.parse import parse_qsmy_values = parse_qs('red=5&blue=0&green=’, keep_blank_values=True)print(repr(my_values))>>>{‘red’: [‘5’], ‘green’: [”], ‘blue’: [‘0’]}
目标:获得qs中第一个数字,没有则返回0
复杂的表达式red = my_values.get(‘red’, [”])red = int(red[0]) if red[0] else 0
辅助函数def get_first_int(values, key, default=0): found = values.get(key, [”]) if found[0]: found = int(found[0]) else: found = default return found
5. 知道如何对序列进行切片 切片可以很简单的实现于 List、str和bytes
切片可以扩展到任何实现了__getitem__
和__setitem__
特殊方法的Python类
基本语法
someList[start:end]
切片之后不是同一对象
>>> a=[1,2,3,4,5,6]>>> b=a[2:]>>> b[2]=c>>> ID(a)1991199427968>>> ID(b)1991199443264>>> a[1, 2, 3, 4, 5, 6]>>> b[3, 4, 99, 6]
6. 避免在单个切片中使用start、end和strIDe strIDe 为 -1 常用于反转字符串
>>> a='abcdefg'>>> a[::-1]'gfedcba'
但是遇到非ASC-II编码时候容易出错 >>> w='谢谢'>>> x=w.encode('utf-8')>>> x[::-1].decode('utf-8')Traceback (most recent call last): @R_301_6852@ "<stdin>", line 1, in <module>UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa2 in position 0: invalID start byte
尽量不要同时使用负值,难以理解
7. 使用列表推导式而不是map和filter# 求 a 中 偶阶方a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# 1. 简单的方法 列表推倒式子even_square = [x**2 for x in a if x%2==0] # [4, 16, 36, 64, 100]#2. 复杂的map搭配filter方法alt=map(lambda x: x**2, filter(lambda x: x%2 ==0,a))
字典和set中的列表推导式# 反转字典res_dict={value,key for key,value in dict}
8. 避免在列表表达式中使用2个以上的表达式难以阅读
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]filtered = [[x for x in row if x % 3 == 0] for row in matrix if sum(row) >= 10]print(filtered)>>>[[6], [9]]
9. 考虑用于大型推导式的生成器表达式 第七点中如果用于读取文件中的行数value = [len(x) for x in open(‘/tmp/my_@R_301_6852@.txt’)]
使用生成器进行替代
it = (len(x) for x in open(‘/tmp/my_@R_301_6852@.txt’))print(it)>>><generator object <genexpr> at 0x101b81480>print(next(it))print(next(it))>>>10057
生成器的另一个强大之处在于可以结合在一起
roots = ((x, x**0.5) for x in it)print(next(roots))>>>(15, 3.872983346207417)
10. 使用enumerate而不是rangeenumerate用惰性生成器包装任何迭代器 这个生成器生成一对循环索引和迭代器中的下一个值 flavor_List = ['vanilla', 'chocolate', 'pecan', 'strawBerry']#遍历列表的range 方法for i in range(len(flavor_List)): flavor = flavor_List[i] print(‘%d: %s’ % (i + 1, flavor))# 简便方法:enumeratefor i, flavor in enumerate(flavor_List): print(‘%d: %s’ % (i + 1, flavor))# 可以指定开始位置for i, flavor in enumerate(flavor_List, 1): print(‘%d: %s’ % (i + 1, flavor))
11. 使用zip并行处理迭代器zip用一个惰性生成器包装了两个或多个迭代器。zip生成器生成元组,其中包含每个迭代器的下一个值names = ['Cecilia', 'lise', 'MarIE']letters = [len(n) for n in names]# 获得最长的名字并记下字母数# 方法1:rangelongest_name = Nonemax_letters = 0for i in range(len(names)): count = letters[i] if count > max_letters: longest_name = names[i] max_letters = count#方法2:enumeratefor i, name in enumerate(names): count = letters[i] if count > max_letters: longest_name = name max_letters = count #方法3:zipfor name, count in zip(names, letters): if count > max_letters: longest_name = name max_letters = count
注意点:如果您不确定zip的列表的长度是否相等,可以考虑使用itertools内置模块中的zip_longest
函数12.避免在for和while循环之后出现else块else 会在正常退出时候执行,而在break时候不会执行
# else被执行for i in range(3): print('Loop %d' % i)else: print('Else block!')>>>Loop 0Loop 1Loop 2Else block# else 未被执行for i in range(3): print(‘Loop %d’ % i) if i == 1: breakelse: print(‘Else block!’)>>>Loop 0Loop 1
13. 利用try/except/else/finally中的每个块UNdefineD = object()def divIDe_Json(path): handle = open(path, ‘r+’) # May raise IOError try: data = handle.read() # May raise UnicodeDecodeError op = Json.loads(data) # May raise ValueError value = ( op[‘numerator’] / op[‘denominator’]) # May raise ZerodivisionError except ZerodivisionError as e: return UNdefineD else: op[‘result’] = value result = Json.dumps(op) handle.seek(0) handle.write(result) # May raise IOError return value finally: handle.close() # Always runs 无论如何都会被执行
总结 以上是内存溢出为你收集整理的改善python——用pythonic的方法思考全部内容,希望文章能够帮你解决改善python——用pythonic的方法思考所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)