当前位置 : 主页 > 编程语言 > python >

编写高质量代码——改善Python程序的91个建议(Ⅳ)

来源:互联网 收集:自由互联 发布时间:2022-06-24
建议36:掌握字符串的基本用法 性质判断:isalnum()、isalpha()、isdigit()、islower()、isupper()、isspace()、istitle()、strartswith()、endswith()。 查找和替换:count()、find()、sub()、rfind()、rindex()。fin
  • 建议36:掌握字符串的基本用法
  • 性质判断:isalnum()、isalpha()、isdigit()、islower()、isupper()、isspace()、istitle()、strartswith()、endswith()。
  • 查找和替换:count()、find()、sub()、rfind()、rindex()。find()函数找不到时返回-1,index()函数则抛出ValueError()异常。对于判定是否包含子串的判断并不推荐调用这些方法,而是推荐in和not in操作符。replace()用以替换字符串的某些子串,如果指定count参数时,就最多替换count次,如果不指定就全部替换。
  • 字符串的分切与连接。partition()、rpartition()、splitlines()、split()、rsplit()。
  • 排版center()、ljust()、rjust()、zfill()、expandtabs()(将字符串中的制表符转换为适量的空格)。
  • 建议37:按需选择sort()或者sorted()
    sorted(iterable[, cmp[, key[, reverse]]])
    s.sort([cmp[, key[, reverse]]])
  • cmp为用户定义的任何比较函数,函数的参数为两个可比较的元素。
  • key是带一个参数的函数,用来为每个元素提取比较值。
  • reverse表示排序结果是否反转。
  • sorted()作用于任意可迭代对象,而sort()一般作用于列表。
  • sorted()会返回一个排序后的列表,sort()函数会直接修改原列表,函数返回None。
  • 传入参数key会比传入参数cmp效率更高。
  • sorted()函数功能非常强大,可以方便的针对不同数据结构进行排序。
  • 对字典进行排序。
  • 多维list排序。
  • 字典中混合list排序。
  • list中混合字典排序。

  • 建议38:使用copy模块深拷贝对象
  • 浅拷贝:构造一个新的复合对象并将原对象中发现的引用插入该对象中。浅拷贝的实现方式有很多中,如工厂函数、切片操作、copy模块中的copy操作等。
  • 深拷贝:也构造一个新的符合对象,但是遇到引用会继续递归拷贝其所指向的内容,也就是说它会针对引用所指向的对象继续执行拷贝,因此产生的对象不受其他引用对象操作的影响。深拷贝的实现需要依赖copy模块的deepcopy()操作。
  • 建议39:使用Counter进行计数统计
In [1]: from collections import Counter

In [2]: some_data = ["a", "2", 2, "b", "2", "a", "z", 4, 7]

In [3]: print(Counter(some_data))
Counter({'a': 2, '2': 2, 2: 1, 4: 1, 'z': 1, 7: 1, 'b': 1})In [4]: Counter("success")
Out[4]: Counter({'c': 2, 'e': 1, 's': 3, 'u': 1})

In [5]: Counter(s=3, c=2, e=1,u=1)
Out[5]: Counter({'c': 2, 'e': 1, 's': 3, 'u': 1})

In [6]: Counter({"s":3,"c":2,"u":1,"e":1})
Out[6]: Counter({'c': 2, 'e': 1, 's': 3, 'u': 1})In [7]: list(Counter(some_data).elements())
Out[7]: [2, 4, 'a', 'a', 'z', '2', '2', 7, 'b']In [8]: Counter(some_data).most_common(2)
Out[8]: [('a', 2), ('2', 2)]
  • 当访问不存在的元素时,默认返回为0为不是抛出异常。
In [9]: (Counter(some_data))['y']
Out[9]: 0In [10]: c = Counter("success")

In [11]: c.update("successfully")

In [12]: c
Out[12]: Counter({'c': 4, 'e': 2, 'f': 1, 'l': 2, 's': 6, 'u': 3, 'y': 1})

-建议40: 深入掌握ConfigParser
配置文件的意义在于用户不需要修改代码,就可以改变应用程序的行为,让它更好地为应用服务。

  • 建议41:使用argparse处理命令行参数
  • 建议42:使用pandas处理大型csv文件
  • reader(csvfile[, dialect=‘excel’[, fmtparam]),主要用于csv文件的读取,返回一个reader对象用于在csv文件内容上进行行迭代。参数csvfile,需要是支持迭代对象,通常对文件对象或者列表对象都是适用的,并且每次调用next()方法的返回值是字符串,参数dialect的默认值为excel,与ecel兼容,fmtparam是一系列参数列表,主要覆盖默认的Dialect设置的情形。
  • csv.writer(csvfile, dialect=‘excel’,**fmtparams),用于写入csv文件。
  • csv.DictReader(csvfile, filednames=None,restkey=None, restval=None, dialect=‘execl’,*args,**kwds)
  • csv.DictWriterr(csv.file,fieldnames,restval=’’,extrasaction=‘raise’,dialect=‘excel’,*args,**kwds)
  • csv模块对大型CSV文件的处理无能为力。
  • Pandas提供了丰富的数据模型,而且支持多种文件格式处理,包括CSV、HDF5、HTML等。能够提供高效的大型数据处理。Series和DataFrame是数据处理的基础。
  • 建议43:一般情况使用ElementTree解析XML
  • 建议44:理解模块pickle优劣
    序列化,简单地说就是把内存中的数据结构在不丢失其身份和类型信息的情况下转成对象的文本或二进制表示的过程。
    python中有很多支持序列化的模块,如pickle、json、marshal和shelve等。
  • pickle之所以能够成为通用的序列化模块,是因为有以下优点:
  • 接口简单,容易使用。通过dump()和load()便可轻易实现序列化和反序列化。
  • pickle的存储格式具有通用性。兼容性好。
  • 支持的数据类型广泛。
  • pickle模块是可以扩展的。
  • pickle存在一定的限制:
  • pickle不能保证操作的原子性。
  • pickle存在安全性问题。
  • pickle协议是Python特定的,不同语言之间的兼容性难以保证。
  • 建议45:序列化的另一个不错的选择——JSON
  • 建议46:使用traceback获取栈信息
    异常处理解决了当发生问题时如何用户友好地提出问题,traceback则面对异常开发人员最希望看到的现场信息。
traceback.print_exc()
  • 建议46:使用logging记录日志信息

Level

适用情形

DEBUG

详细的信息,在追踪问题的时候使用

INFO

正常的信息

WARNING

一些不可预见的问题的发生,或将要发生,如磁盘空间低等,但不影响程序的运行

ERROR

由于某些严重的问题,程序中的一些功能受到影响

CRITICAL

严重的错误,或者程序本身不能够继续运行

import traceback
import sys
import logging
gList = ['a', 'b', 'c', 'd', 'e', 'f', 'g',]
logging.basicConfig(# 配置日志的输出方式及格式
level = logging.DEBUG,
filename = 'log.txt',
filemode = 'w',
format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
)

def f():
gList[5]
logging.info('[INFO]:calling method g() in f()') #记录正常的信息
return g()

def g():
logging.info('[INFO]:calling method h() in g()')
return h()

def h():
logging.info('[INFO]:Delete element in gList in h()')
del gList[2]
logging.info('[INFO]:calling method i() in h()')
return i()

def i():
logging.info('[INFO]:Append element i to gList in i()')
gList.append("i")
print(gList[7])

if __name__ == "__main__":
logging.debug('Information during calling f():')
try:
f()
except IndexError as ex:
print("Sorry,Exception occured, you accessed an element out of range.")
ty, tv, tb = sys.exc_info()
logging.error("[ERROR]:Sorry, Exception occured, you accessed an element out of range.")
logging.critical("object info:%s" % ex)
logging.critical(''.join(traceback.format_tb(tb)))
sys.exit(1)2019-10-07 13:45:31,080 日志样例.py[line:33] DEBUG Information during calling f():
2019-10-07 13:45:31,200 日志样例.py[line:14] INFO [INFO]:calling method g() in f()
2019-10-07 13:45:31,200 日志样例.py[line:18] INFO [INFO]:calling method h() in g()
2019-10-07 13:45:31,200 日志样例.py[line:22] INFO [INFO]:Delete element in gList in h()
2019-10-07 13:45:31,200 日志样例.py[line:24] INFO [INFO]:calling method i() in h()
2019-10-07 13:45:31,200 日志样例.py[line:28] INFO [INFO]:Append element i to gList in i()
2019-10-07 13:45:31,210 日志样例.py[line:39] ERROR [ERROR]:Sorry, Exception occured, you accessed an element out of range.
2019-10-07 13:45:31,210 日志样例.py[line:40] CRITICAL object info:list index out of range
2019-10-07 13:45:31,210 日志样例.py[line:41] CRITICAL File "C:/Users/83735/Desktop/日志样例.py", line 35, in <module>
f()
File "C:/Users/83735/Desktop/日志样例.py", line 15, in f
return g()
File "C:/Users/83735/Desktop/日志样例.py", line 19, in g
return h()
File "C:/Users/83735/Desktop/日志样例.py", line 25, in h
return i()
File "C:/Users/83735/Desktop/日志样例.py", line 30, in i
print(gList[7])
  • 建议48:使用threading模块编写多线程程序
  • 建议49:使用Queue使多线程编程更安全

- 《编写高质量代码 改善Python程序的91个建议》张颖 赖勇浩 著。


网友评论