改善python——用pythonic的方法思考

改善python——用pythonic的方法思考,第1张

概述1.知道你使用的python的版本命令行python-version程序内importsysprint(sys.version_info)print(sys.version)2.遵循PEP8的风格PythonEnhancementProposal#8在线文档http://www.python.org/dev/peps/pep-0008/规则例子space空格缩进使用spaces 1. 知道你使用的python的版本

命令行

python -version

程序内

import sysprint(sys.version_info)print(sys.version)
2. 遵循PEP8的风格

Python Enhancement Proposal #8

在线文档 http://www.python.org/dev/peps/pep-0008/规则例子space空格缩进使用spaces 代替 tabs每一级的缩进使用四个spaces每行79个字符或者更少长表达式换行也要缩进四个空格函数与函数、类与类之间 必须被两个空行分开类的函数需要被一行空行分开不要在列表索引、函数调用或关键字参数赋值周围放空格在变量赋值的前后放且仅放一个空格命名函数变量属性应采用小写下划线格式私有实例属性应该采用__double_leading_下划线格式异常应该大写模块级常量应该是ALL_CAPS格式类中的实例方法应该使用self作为第一个参数的名称类方法应该使用cls作为第一个参数的名称表达式和语句使用内联否定(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之间的差别字符串的表达
版本表达方法
python2unicode 和 str
python3bytes 和 str
区分有很多的方法可以将Unicode转为二进制数据,最常见的方法就是UTF-8python 3 中的 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_@[email protected]’)]

文件大的时候会占用大量内存

使用生成器进行替代

it = (len(x) for x in open(‘/tmp/my_@[email protected]’))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的方法思考所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1187966.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存