Python使用总结二
近来因为工作需要,用Python比较多,写得多了,收获也多。借此记录总结一下,方便以后反思。
一、IDE的选择
1、notepad++加上cmd窗口
前些时候写python脚本都用notepad++编辑代码,然后用控制台运行。当时觉得这样挺方便,不用去折腾IDE。这种组合对编写一些代码量不多,且使用的模块是自己熟悉的脚本是可以的,极推荐使用。但由于没有工程管理,源代码文件的存放可能会比较乱,而且没有代码提示功能,代码产出的效率比较低。
2、eric5 与eclipse 加 pydev
发现notepad++满足不了我的需求后,我便开始为python配一个IDE开发环境。
首先尝试的是eric5,因为网上评分很高。而且它还是用QT写的,用python开发GUI程序应该很方便。不过让人纠结的是eric5的代码提示功能很弱,只能提示自带的模块,对第三方模块,如我装的win32com模块不能提示。唉~~,看来只好另寻IDE了。
最后改用了eclipse + pydev的环境,eclipse就一神器,代码提示能力甩eric5几条街。不过它很吃内存,但做开发的,你的机器没个4G以上,说不过去吧,所以内存这方面不是大问题,就选它了。配置也比较简单,网上很多前辈给出了方法。
二、xml操作
Python自带有xml相关模块xml.etree.ElementTree与xml.dom.minidom。在使用的过程中,我用xml.etree.ElementTree来对xml文件进行读,用xml.dom.minidom对xml文件进行写操作。相关模块使用可以查看python手册,地址如下:
http://docs.python.org/2/library/xml.etree.elementtree.html
http://docs.python.org/2/library/xml.dom.minidom.html
以下给出的代码是实现对两个xml文件进行节点比较,并把不同的结点信息生成一个新的xml文件。代码覆盖了xml文件的读与写操作。
1 import xml.etree.ElementTree as ET 2 import sys, os 3 4 # 属性比较 5 def compare_attr(dictattr1, dictattr2): 6 dictvalue = {} 7 # dictattr1 - dictattr2 8 diffLis = dictattr1.keys() - dictattr2.keys() 9 print (diffLis) 10 for item in diffLis: 11 dictvalue[item] = "only ({0}) exist attrib".format(os.path.split(sys.argv[1])[1]) 12 # dictattr2 - dictattr1 13 diffLis = dictattr2.keys() - dictattr1.keys() 14 print (diffLis) 15 for item in diffLis: 16 dictvalue[item] = "only ({0}) exist attrib".format(os.path.split(sys.argv[2])[1]) 17 18 # dictattr2 & dictattr1 19 andList = dictattr1.keys() & dictattr2.keys() 20 #print (andList) 21 for key in andList: 22 if dictattr1[key] != dictattr2[key]: 23 dictvalue[key] = "different_value({0})and({1})".format(dictattr1[key], dictattr2[key]) 24 return dictvalue 25 26 def getAttribute(node): 27 if node == None: 28 return dict() 29 else: 30 return node.attrib 31 32 def getChildren(node): 33 if node == None: 34 return list() 35 else: 36 return node.getchildren() 37 38 #节点比较 39 def compare_xmltree(root1, root2, domTree, xmlNode): 40 if root1 == None or root2 == None: 41 strValue = "" 42 if root2 == None: 43 strValue = "only ({0}) has the Node and ChildrenNode".format(os.path.split(sys.argv[1])[1]) 44 else: 45 strValue = "only ({0}) has the Node and ChildrenNode".format(os.path.split(sys.argv[2])[1]) 46 47 xmlNode.setAttribute("differentNode", strValue) 48 return True 49 50 dictvalue = compare_attr(getAttribute(root1), getAttribute(root2)) 51 if len(dictvalue) > 0: 52 for k, v in dictvalue.items(): 53 xmlNode.setAttribute(k, v) 54 55 #取孩子结点 56 childrenlist1 = getChildren(root1) 57 childrenlist2 = getChildren(root2) 58 print (childrenlist1) 59 print (childrenlist2) 60 list1 = [child.tag for child in childrenlist1] 61 list2 = [child.tag for child in childrenlist2] 62 set1 = set(list1) 63 set2 = set(list2) 64 65 diffSet = set2 & set2 66 print (diffSet) 67 for item in diffSet: 68 index1 = list1.index(item) 69 index2 = list2.index(item) 70 childnode = domTree.createElement(item) 71 compare_xmltree(childrenlist1[index1], childrenlist2[index2], domTree, childnode) 72 if childnode.hasAttributes() or childnode.hasChildNodes(): 73 xmlNode.appendChild(childnode) 74 75 diffSet = set1 - set2 76 print (diffSet) 77 for item in diffSet: 78 index = list1.index(item) 79 childnode = domTree.createElement(item) 80 compare_xmltree(childrenlist1[index], None, domTree, childnode) 81 if childnode.hasAttributes() or childnode.hasChildNodes(): 82 xmlNode.appendChild(childnode) 83 84 diffSet = set2 - set1 85 print (diffSet) 86 for item in diffSet: 87 index = list2.index(item) 88 childnode = domTree.createElement(item) 89 compare_xmltree(None, childrenlist2[index], domTree, childnode) 90 if childnode.hasAttributes() or childnode.hasChildNodes(): 91 xmlNode.appendChild(childnode) 92 93 return True 94 95 if __name__ == "__main__": 96 from xml.dom import minidom 97 tree1 = ET.parse(sys.argv[1]) 98 tree2 = ET.parse(sys.argv[2]) 99 root1 = tree1.getroot() 100 root2 = tree2.getroot() 101 if root1.tag != root2.tag: 102 print ("两个xml文件的根结点不同,不能比较") 103 sys.exit(0) 104 #生成domTree 105 impl = minidom.getDOMImplementation() 106 dom = impl.createDocument(None, None, None) 107 108 #i添加节点 109 root = dom.createElement(root1.tag) 110 compare_xmltree(root1, root2, dom, root) 111 if root.hasAttributes() or root.hasChildNodes(): 112 dom.appendChild(root) 113 114 save2file = "" 115 if sys.argv[3][1] == ":": 116 save2file = sys.argv[3] 117 else: 118 save2file = os.getcwd() + "\\" + sys.argv[3] 119 120 file = open(save2file, "w", encoding = 'UTF8') 121 dom.writexml(file, "","\t", "\n", "utf-8") 122 file.close()
三、win32com模块
win32com模块里面能做的事情很多,但我只调用这个模块对com对象的操作功能,通过dispatch调用WPP(金山办公软件演示),并通过类似vba的语句来对它进行操作。给出的代码示例是查找一个文档里面是否含有flash对象。
1 import win32com.client 2 import os, sys 3 4 5 def findFlashFile(fileName): 6 wpp = win32com.client.Dispatch('wpp.application') 7 wpp.visible = True 8 9 if wpp.Presentations.count > 1: 10 print (wpp.Presentations.count) 11 for i in range(wpp.Presentations.count): 12 wpp.Presentations[0].close 13 14 isHasFlash = False 15 pres = wpp.Presentations.Open(fileName, ReadOnly = -1) 16 17 for slide_i in range(1, pres.slides.count + 1): 18 slide = pres.slides(slide_i) 19 for shape_i in range(1, slide.shapes.count + 1): 20 shape = pres.slides(slide_i).shapes(shape_i) 21 if shape.Type == 12: 22 print (shape.OLEFormat.ClassType) 23 shapeType = shape.OLEFormat.ClassType 24 print (shapeType.find("ShockwaveFlash.ShockwaveFlash")) 25 if shapeType.find("ShockwaveFlash.ShockwaveFlash") > -1: 26 print ("slid{0}, shape{1} has flash".format(slide_i, shape_i)) 27 pres.saved = True 28 pres.close 29 return True 30 pres.saved = True 31 pres.close 32 return isHasFlash 33
四、发送邮件
一直想写一个自动发送邮件的程序,弄了好久,终于搞出来了。使用的是smtp协议。代码好下,从配置文件里面读取邮件服务器及相关信息。
1 import smtplib 2 from email.mime.multipart import MIMEMultipart 3 from email.mime.text import MIMEText 4 import os 5 6 def smtpInit(dict_value): 7 SMTPserver = dict_value["SMTPserver"] 8 s = smtplib.SMTP(SMTPserver) 9 s.set_debuglevel(1) 10 s.login(dict_value["Account"], dict_value["PassWord"]) 11 return s 12 13 def loadFile(fileName, msgRoot): 14 att = MIMEText(open(fileName, "rb").read(), 'base64', 'gb2312') 15 att['Content-Type'] = 'application/octet-stream' 16 att["Content-Disposition"] = 'attachment; filename=%s'%os.path.split(fileName)[1] 17 msgRoot.attach(att) 18 19 def checkFile(fileName): 20 return os.path.exists(fileName) 21 22 23 def sendMail(dict_value, func_smtp_init): 24 25 msgRoot = MIMEMultipart('related') 26 msgRoot['Subject'] = dict_value["Subject"] 27 msgRoot['to'] = dict_value["toaddr"] 28 msgRoot['from'] = dict_value["fromaddr"] 29 30 file = open(dict_value["Text"]) 31 str = file.read() 32 file.close() 33 msgText = MIMEText(str,'html','utf-8') 34 msgRoot.attach(msgText) 35 os.remove(dict_value["Text"]) 36 37 list = dict_value["Attachment"].split(";") 38 for filename in list: 39 filename = filename.strip() 40 print (filename) 41 if (checkFile(filename) == True): 42 loadFile(filename, msgRoot) 43 44 s = func_smtp_init(dict_value) 45 s.sendmail(dict_value["fromaddr"], dict_value["toaddr"], msgRoot.as_string().encode('utf-8')) 46 s.quit() 47 48 if __name__ == "__main__": 49 import sys 50 #打开配置文件 51 file = open(sys.argv[1]) 52 dict_value = dict() 53 for line in file.readlines(): 54 list = line.strip().split(" ") 55 dict_value[list[0]] = list[2] 56 file.close() 57 print (dict_value) 58 sendMail(dict_value, smtpInit)
SMTPserver : ***.***.com Account : ****** PassWord : ****** fromaddr : ****** toaddr : ****** Subject : 能过python程序发送邮件 Text : message.txt(将要发送的邮件的内容,存到这个文件里,这里指定路径) Attachment : deal_result\result_success.xml;deal_result\result_failed.xml(发送的附件的路径)