近来因为工作需要,用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文件的读与写操作。
import xml.etree.ElementTree as ET
import sys, os # 属性比较
def compare_attr(dictattr1, dictattr2):
dictvalue = {}
# dictattr1 - dictattr2
diffLis = dictattr1.keys() - dictattr2.keys()
print (diffLis)
for item in diffLis:
dictvalue[item] = "only ({0}) exist attrib".format(os.path.split(sys.argv[1])[1])
# dictattr2 - dictattr1
diffLis = dictattr2.keys() - dictattr1.keys()
print (diffLis)
for item in diffLis:
dictvalue[item] = "only ({0}) exist attrib".format(os.path.split(sys.argv[2])[1]) # dictattr2 & dictattr1
andList = dictattr1.keys() & dictattr2.keys()
#print (andList)
for key in andList:
if dictattr1[key] != dictattr2[key]:
dictvalue[key] = "different_value({0})and({1})".format(dictattr1[key], dictattr2[key])
return dictvalue def getAttribute(node):
if node == None:
return dict()
else:
return node.attrib def getChildren(node):
if node == None:
return list()
else:
return node.getchildren() #节点比较
def compare_xmltree(root1, root2, domTree, xmlNode):
if root1 == None or root2 == None:
strValue = ""
if root2 == None:
strValue = "only ({0}) has the Node and ChildrenNode".format(os.path.split(sys.argv[1])[1])
else:
strValue = "only ({0}) has the Node and ChildrenNode".format(os.path.split(sys.argv[2])[1]) xmlNode.setAttribute("differentNode", strValue)
return True dictvalue = compare_attr(getAttribute(root1), getAttribute(root2))
if len(dictvalue) > 0:
for k, v in dictvalue.items():
xmlNode.setAttribute(k, v) #取孩子结点
childrenlist1 = getChildren(root1)
childrenlist2 = getChildren(root2)
print (childrenlist1)
print (childrenlist2)
list1 = [child.tag for child in childrenlist1]
list2 = [child.tag for child in childrenlist2]
set1 = set(list1)
set2 = set(list2) diffSet = set2 & set2
print (diffSet)
for item in diffSet:
index1 = list1.index(item)
index2 = list2.index(item)
childnode = domTree.createElement(item)
compare_xmltree(childrenlist1[index1], childrenlist2[index2], domTree, childnode)
if childnode.hasAttributes() or childnode.hasChildNodes():
xmlNode.appendChild(childnode) diffSet = set1 - set2
print (diffSet)
for item in diffSet:
index = list1.index(item)
childnode = domTree.createElement(item)
compare_xmltree(childrenlist1[index], None, domTree, childnode)
if childnode.hasAttributes() or childnode.hasChildNodes():
xmlNode.appendChild(childnode) diffSet = set2 - set1
print (diffSet)
for item in diffSet:
index = list2.index(item)
childnode = domTree.createElement(item)
compare_xmltree(None, childrenlist2[index], domTree, childnode)
if childnode.hasAttributes() or childnode.hasChildNodes():
xmlNode.appendChild(childnode) return True if __name__ == "__main__":
from xml.dom import minidom
tree1 = ET.parse(sys.argv[1])
tree2 = ET.parse(sys.argv[2])
root1 = tree1.getroot()
root2 = tree2.getroot()
if root1.tag != root2.tag:
print ("两个xml文件的根结点不同,不能比较")
sys.exit(0)
#生成domTree
impl = minidom.getDOMImplementation()
dom = impl.createDocument(None, None, None) #i添加节点
root = dom.createElement(root1.tag)
compare_xmltree(root1, root2, dom, root)
if root.hasAttributes() or root.hasChildNodes():
dom.appendChild(root) save2file = ""
if sys.argv[3][1] == ":":
save2file = sys.argv[3]
else:
save2file = os.getcwd() + "\\" + sys.argv[3] file = open(save2file, "w", encoding = 'UTF8')
dom.writexml(file, "","\t", "\n", "utf-8")
file.close()
三、win32com模块
win32com模块里面能做的事情很多,但我只调用这个模块对com对象的操作功能,通过dispatch调用WPP(金山办公软件演示),并通过类似vba的语句来对它进行操作。给出的代码示例是查找一个文档里面是否含有flash对象。
import win32com.client
import os, sys def findFlashFile(fileName):
wpp = win32com.client.Dispatch('wpp.application')
wpp.visible = True if wpp.Presentations.count > 1:
print (wpp.Presentations.count)
for i in range(wpp.Presentations.count):
wpp.Presentations[0].close isHasFlash = False
pres = wpp.Presentations.Open(fileName, ReadOnly = -1) for slide_i in range(1, pres.slides.count + 1):
slide = pres.slides(slide_i)
for shape_i in range(1, slide.shapes.count + 1):
shape = pres.slides(slide_i).shapes(shape_i)
if shape.Type == 12:
print (shape.OLEFormat.ClassType)
shapeType = shape.OLEFormat.ClassType
print (shapeType.find("ShockwaveFlash.ShockwaveFlash"))
if shapeType.find("ShockwaveFlash.ShockwaveFlash") > -1:
print ("slid{0}, shape{1} has flash".format(slide_i, shape_i))
pres.saved = True
pres.close
return True
pres.saved = True
pres.close
return isHasFlash
四、发送邮件
一直想写一个自动发送邮件的程序,弄了好久,终于搞出来了。使用的是smtp协议。代码好下,从配置文件里面读取邮件服务器及相关信息。
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import os def smtpInit(dict_value):
SMTPserver = dict_value["SMTPserver"]
s = smtplib.SMTP(SMTPserver)
s.set_debuglevel(1)
s.login(dict_value["Account"], dict_value["PassWord"])
return s def loadFile(fileName, msgRoot):
att = MIMEText(open(fileName, "rb").read(), 'base64', 'gb2312')
att['Content-Type'] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename=%s'%os.path.split(fileName)[1]
msgRoot.attach(att) def checkFile(fileName):
return os.path.exists(fileName) def sendMail(dict_value, func_smtp_init): msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = dict_value["Subject"]
msgRoot['to'] = dict_value["toaddr"]
msgRoot['from'] = dict_value["fromaddr"] file = open(dict_value["Text"])
str = file.read()
file.close()
msgText = MIMEText(str,'html','utf-8')
msgRoot.attach(msgText)
os.remove(dict_value["Text"]) list = dict_value["Attachment"].split(";")
for filename in list:
filename = filename.strip()
print (filename)
if (checkFile(filename) == True):
loadFile(filename, msgRoot) s = func_smtp_init(dict_value)
s.sendmail(dict_value["fromaddr"], dict_value["toaddr"], msgRoot.as_string().encode('utf-8'))
s.quit() if __name__ == "__main__":
import sys
#打开配置文件
file = open(sys.argv[1])
dict_value = dict()
for line in file.readlines():
list = line.strip().split(" ")
dict_value[list[0]] = list[2]
file.close()
print (dict_value)
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(发送的附件的路径)