《编写高质量代码 改善Python程序的91个建议》Chapter4笔记(三)

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
__author__ = 'Abel'

#建议43:一般使用ElementTree解析XML
import xml.dom.minidom
import xml.sax
#这两个是常用的XML解析模块
#dom将XML文件加在到内存中并解析为一棵树,占用内存比较大
import xml.etree.ElementTree as ET
tree=ET.ElementTree(file="test.xml")
root=tree.getroot()
print(root) #<Element 'doc' at 0x000002312EE6A818>
for i in tree.iter(tag="name"): #查找结点
    print(i.text) #Microsoft.Transactions.Bridge.Dtc

#建议44:理解模块pickle的优劣
#在实际应用中,序列化的场景很常见,如:在磁盘上保存当前程序的状态数据以便重启的时候能够重新加载;多用户或者分布式系统中数据结构的网络传输时,
# 可以将数据序列化后发送给一个可信网络对端,接收者进行反序列化后便可以重新恢复相同的对象; Session和cache的存储等。
# 序列化,简单地说就是把内存中的数据结构在不丢失其身份和类型信息的情况下转成对象的文本或二进制表示的过程。
#对象序列化后的形式经过反序列化过程应该能恢复为原有对象。 Python中有很多支持序列化的模块,如 pickle、 Json、 marshal和 shelve等。最广为人知的为 pickle。
import pickle
my_data = {"name":"python","type":"Language","version":"3.6"}
fp = open("pickle.dat","wb")
pickle.dump(my_data, fp)
fp.close()
fpo = open("pickle.dat","rb")
out = pickle.load(fpo)
print(out)

#建议45:序列化的另一个不错的选择 ---JSON
import json

#建议46:使用traceback获取栈信息
gList = ["a","s","w","e"]
import traceback
#print(traceback.print_exc()) #None

#建议47:使用logging记录日志信息
import logging
#Python中自带的 logging模块提供了日志功能,它将 logger的 level分为5个级别,可以通过 Logger set Level(v)来设置,其中DEBUG为最低级别,
# CRIIICAL为最高级别,默认的级别为 WARNING
#DEBUG   详细的信息,在追踪问题的时候使用
# INFO   正常的信息
# WARNING一些不可预见的问题发生,或者将要发生,如磁盘空间低等,但不影响程序的运行
# ERROR  由于某些严重的问题,程序中的一些功能受到影响
# CRITICAL    严重的错误,或者程序本身不能够继续运行
logging.basicConfig(level=logging.DEBUG,
                    filename="log.txt",
                    filemode="w",
                    format="%(asctime)s%(filename)s[line:%(lineno)d]%(levelname)s%(message)s",)
def testlog():
    logging.info("[INFO]:This is only for test logging info!")

testlog()

#建议48:使用threading模块编写多线程
#执行环境如JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,
# 也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。
#GIL的存在使得 Python多线程编程暂时无法充分利用多处理器的优势,对于只含纯 Python的代码也许使用多线程并不能提高运行速率,
# 但在以下几种情况,如等待外部资源返回,或者为了提高用户体验而建立反应灵活的用户界面,或者多用户应用程序中,多线程仍然是一个比较好的解决方案。
#Python为多线程编程提供了两个非常简单明了的模块: thread和threading。那么,这两个模块在多线程处理上有什么区别呢?
# 简单一点说: thread模块提供了多线程底层支持模块,以低级原始的方式来处理和控制线程,使用起来较为复杂;而threading模块基于thread进行包装,
# 将线程的操作对象化,在语言层面提供了丰富的特性。Python多线程支持用两种方式来创建线程:一种是通过继承 Thread类,重写它的run()方法(注意,不是 start()方法);
# 另一种是创建一个 threading Thread对象,在它的初始化函数(__init__())中将可调用对象作为参数传人。
import threading,sys,time
class test(threading.Thread):
    def __init__(self,name,delay):
        threading.Thread.__init__(self)
        self.name = name
        self.delay = delay
    def run(self):
        print("%s delay for %s" % (self.name, self.delay))
        time.sleep(self.delay)
        c = 0
        while(True):
            print("This is thread %s on line %s " % (self.name, c))
            c = c+1
            if c == 3:
                print("End of Thread %s " % (self.name))
                break

t1 = test("Thread1", 2)
t2 = test("Thread2", 3)
t1.start()
print("wait t1 to the end")
t1.join() #主线程main在t1上使用join()的方法,主线程会等待t1结束后才继续运行后面的语句,
#由于线程t2的启动在join()之后,t2会一直等待t1退出之后才会开始运行。
t2.start()
print("End The main")
"""
输出:
Thread1 delay for 2
wait t1 to the end
This is thread Thread1 on line 0 
This is thread Thread1 on line 1 
This is thread Thread1 on line 2 
End of Thread Thread1 
Thread2 delay for 3
End The main
This is thread Thread2 on line 0 
This is thread Thread2 on line 1 
This is thread Thread2 on line 2 
End of Thread Thread2 
"""
#Thread模块不支持守护线程。thread模块中主线程退出的时候,所有的子线程不论是否还在工作,
#都会强制结束,并且没有任何的警告,也没有任何的清理工作。
#实际上很多情况下我们可能希望主线程能够等待所有子线程都完成时才退出,这时应该使用 threading模块,它支持守护线程,
# 可以通过 setdaemon0函数来设定线程的 daemon属性。当 daemon属性设置为True的时候表明主线程的退出可以不用等待子线程完成。
# 默认情况下, daemon标志为 False,所有的非守护线程结束后主线程才会结束。来看具体的例子,当 daemon属性设置为 False,默认主线程会等待所有子线程结束才会退出。
#python3中已经不存在thread模块,thread模块在Python3中被命名为_thread。

#建议49:使用Queue使多线程更安全
#举例:生产者向队列放商品,消费者从队列取商品,队列满了生产者等待,队列为空消费者等待。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算机视觉与OpenCV

客官,,打赏是什么意思?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值