这篇文章解决了困扰我许久的疑问,实在太好了,网上所有的乱七八糟的说明,还不如这个来的完善,直接将文章链接放在最上面。
原文链接: Chris Beaumont 翻译: 极客范 – 慕容老匹夫
译文链接: http://www.geekfan.net/7862/
文艺技术宅
这篇文章解决了困扰我许久的疑问,实在太好了,网上所有的乱七八糟的说明,还不如这个来的完善,直接将文章链接放在最上面。
原文链接: Chris Beaumont 翻译: 极客范 – 慕容老匹夫
译文链接: http://www.geekfan.net/7862/
左移和右移N位等同于无溢出检查的2的N次幂运算:2**N
<<左移
运算规则:
按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
语法格式:
需要移位的数字<<移位的位数
例如:3<<2则是将数字3左移动2位
计算过程:
3<<2首先把3转换为二进制数字00000000000000000000000000000011
然后把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,最后在低位(右侧)
的连个空位补零。则得到的结果是00000000000000000000000000001100,
则转换为十进制是12
数学意义:
在数学没有溢出的前提下,对于正数和负数,左移以为都相当于乘以2的1次方,左移n位
就相当于乘以2的n次方
>>右移
运算规则:
按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位
即正数补0,负数补1
语法规则:
需要移位的数字>>移位的次数
例如:11>>2则是将数字11右移2位
计算过程:
11的二进制形式为:00000000000000000000000000001011然后把低位的最
后两个数字移出,因为该数字是正数,所以在高位补0,则得到的最终的二进制结果为:
00000000000000000000000000000010转换为十进制数为3
数学意义:
右移一位相当于除以2,右移n位相当于除以2的n次方,这里取的是商,不要余数
转自:http://wangyan112.blog.51cto.com/3383033/1320143
Python 2.2以后使用super继承的父类属性的时候会报错,这篇文章通过讲解新式类和旧类的区别来解决super报错的问题。
Python 2.2以后使用super继承的父类属性的时候会报错,这篇文章通过讲解新式类和旧类的区别来解决super报错的问题。
在Python的类中去继承父类的属性, 一般的写法为:
class Father: def __init__(self): print "I'm Father" class Child(Father): def __init__(self): Father.__init__(self) print "I'm Child" >>>f = Child() I'm Father I'm Child
如果在多重继承的问题中,例如菱形继承(钻石问题),则需要用到super来解决。但是super只能用在继承基类”object”的新式类中,不能用于以前的经典类,否则报错:
class Father: def __init__(self): print "I'm Father" class Child(Father): def __init__(self): super(Child, self).__init__() print "I'm Child" >>>f = Child() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in __init__ TypeError: must be type, not classobj
原因如下:
解决的方法是设置Father继承Object
class Father(object): def __init__(self): print "I'm Father" class Child(Father): def __init__(self): super(Child, self).__init__() print "I'm Child" >>>f = Child() I'm Father I'm Child
以下关于《旧类和新式类》的内容摘自:http://blog.csdn.net/jb19900111/article/details/20228341
Pyinstaller可以将Python程序编译成可执行程序,它可以被用于多个平台,操作十分的简单。 这次将Wiki Export Tool图形化后,需要生成一个可执行的文件,这样其他用户可以不用安装相关包就可以直接使用,这时候需要用到Pyinstaller将Python的程序转成可执行文件。
Pyinstaller可以将Python程序编译成可执行程序,它可以被用于多个平台,操作十分的简单。 这次将Wiki Export Tool图形化后,需要生成一个可执行的文件,这样其他用户可以不用安装相关包就可以直接使用,这时候需要用到Pyinstaller将Python的程序转成可执行文件。
这篇文章将会以转Wiki Export Tool为例子,介绍一下简单的操作。
这是一篇关于Python加载目录中的模块的一个简单方法,可以用于模块开发。
这是一篇关于Python加载目录中的模块的一个简单方法,可以用于模块开发。
关于package
通常包总是一个目录,可以使用import导入包:
import re #加载正则表达式
或者from + import来导入包中的部分模块:
from time import datetime #从时间包中加载日期模块
如何创建一个包呢?
主要的一个文件是,包目录下为首的一个文件便是 __init__.py,内容可以为空。
也就是说模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。
Python牛逼小技巧,Python保留分隔符的Split方法。
Python牛逼小技巧,Python保留分隔符的Split方法。其实在Python手册里面写了很清楚,因为原来用不着,所以没注意,但是这次因为处理文本的时候,需要保留标点符号,因此特地的去查了一下。
>>>re.split('(W)', 'foo/bar spamneggs') ['foo', '/', 'bar', ' ', 'spam', 'n', 'eggs']
在使用PYQT写程序的时候,会遇到某些PYTHON中的函数不能用了,究其原因是因为在使用PYQT读取数据后,数据类型已经不是在PYTHON上的数据类型了,这里给了一个例子介绍了如何将数据类型转换回PYTHON的。
在使用PYQT写程序的时候,会遇到某些PYTHON中的函数不能用了,比如说针对QString就没有strip(),join的使用方式变成了list.join(“,”)逗号是分割符。究其原因是因为在使用PYQT读取数据后,数据类型已经不是在PYTHON上的数据类型了,随便找一个看看,比如
#文本编辑块 self.textEdit_articlelist.toPlainText() #输出文本编辑内容类型 print type(self.textEdit_articlelist.toPlainText()) #得出其类别 <class 'PyQt4.QtCore.QString'>
会发现她们的数据类型会是:
那么要如何解决呢,很简单比如这个字符串类型的数据,通过str()转回到Python的数据类型就是了,就是这么简单的。
附上Pyqt4的使用指南:http://pyqt.sourceforge.net/Docs/PyQt4/
大数据处理中,常常会遇到压缩后的数据包,比如BZ2,ZIP等格式,这里简单的介绍了Python在无解压的情况下读取BZ2压缩文件,另外通过lxml中iterparse()的对于XML大型文件处理的方法。
大数据处理中,常常会遇到压缩后的数据包,比如BZ2,ZIP等格式,这里简单的介绍了Python在无解压的情况下读取BZ2压缩文件,另外通过lxml中iterparse()的对于XML大型文件处理的方法。
在处理维基百科的DUMP包的时候,会遇到一个问题:大数据,几乎每一个DUMP在解压后都有400-500GB,没有解压之前如果是BZ2格式的话,大小也在20-30GB之间。
对于大数据的一般处理顺序:解压压缩包,再处理。可是把所有压缩包解压,可能没有足够的硬盘空间, 而且也很费时间。那么就试试不解压的情况下来操作,整个过程都在Python 2.7.*的环境下运行。
BZ2文件:
#加载bz2模块 from bz2 import BZ2File as b2f fp = b2f("filename.bz2") #filename.bz2是要处理的压缩包名字 line = fp.readline() #读取一行 while line: #按行读取,并自动读完的时候停止 print line line = fp.readline()
现在我们知道了如何在不解压的情况下处理bz2格式的文件,那么维基百科提供的DUMP都按照BZ2格式的压缩,而且里面的文件是XML文件,那么该如何处理维基百科的数据呢?
Python提供了xml.sax来处理XML大型文件,而且这个处理方式完全可以和上面的方式联合来直接操作20几个GB的数据包。这里就介绍一下操作方式,下面这段SAX代码引子别处,并且在上面做了一些修改, 源代码网址:http://my.oschina.net/renhc/blog/59646
from bz2 import BZ2File as b2f #加载bz2模块 from xml.sax import parse, handler, SAXException class MyXMLSAXHandler(handler.ContentHandler): """ 用户自定义事件处理器 """ #文档开始事件处理 def startDocument(self): print 'Document Start...' #文档结束事件处理 def endDocument(self): print 'Document End...' #元素开始事件处理 #"name"是节点名称,"attrs"是节点属性 def startElement(self, name, attrs): print 'encounter element(%s)' % (name) #元素结束事件处理 def endElement(self, name): print 'leave element(%s)' % (name) #内容事件处理 def characters(self, content): if content.isspace(): #去掉内容中的空格 return print 'characters:' + content try: fp = b2f("filename.bz2","r") #filename.bz2是要处理的压缩包名字 parse(fp, MyXMLSAXHandler()) except SAXException, msg: print msg.getException() except: print sys.exc_info()[0],sys.exc_info()[1]
这段代码其实不难理解,类MyXMLSAXHander继承了handler.ContentHandler, 在parse()分析XML文件是,从头到尾像流水一下的处理文件,类似与逐行读取,并在读取到相应的节点的时候,进行相关处理。
也许通过xml.sax来控制数据还是比较复杂且花费时间,那么可以试试lxml中提供的iterparse(),这个方法基于SAX,操作大型数据就变的简单多了,类似的Python自身也提供了iterparse()模块, 有兴趣的可以移步:
http://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.iterparse, 小提示:xml.etree.ElementTree和xml.etree.cElementTree都可以用哦,后者基于C的模块,速度会更快一些。 废话不多说,直接进入lxml.etree.iterparse()的用法,后面清除内存的那块一定得加。
from bz2 import BZ2File as b2f from lxml import etree f1 = "filename.xml.bz2" fp = b2f(f1,"r") node_find = "page" #要寻找的节点的名字 #fp上面的传送过来的一个Objet, 其实也可以是一个文件名。 #end是某个节点的结尾 tree = etree.iterparse(fp,events=("end",), tag=node_find) for event, elem in tree: #输出结果 print etree.tostring(elem, encoding="utf-8", pretty_print=True, xml_declaration=True) #清除内存 elem.clear() while elem.getprevious() is not None: del elem.getparent()[0]
好了,就到这里,如问题请留言。
python def定义了一个方法(函数/模块),他们的内存使用方式很简单,调用完就清楚内存,但是有特别的情况比如调用模块libxml2。
python在通过def定义了一个方法后,每次调用这个模块,都将进行内存加载。但是一旦使用完整个方法并返回后,python的内存管理机制,将会自动将所有的内存清空。网上已经有很多文章讲解内存管理机制,因此这里就简单的引用一下别人的文章,做个记录。
关于Python的内存管理机制,这里引用51cto的一篇文章中提到的:
“在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。
这就意味着Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。这也就是之前提到的Pymalloc机制。
在Python 2.5中,Python内部默认的小块内存与大块内存的分界点定在256个字节,这个分界点由前面我们看到的名为SMALL_REQUEST_THRESHOLD的符号控制。
也就是说,当申请的内存小于256字节时,PyObject_Malloc会在内存池中申请内存;当申请的内存大于256字节时,PyObject_Malloc的行为将蜕化为malloc的行为。当然,通过修改Python源代码,我们可以改变这个默认值,从而改变Python的默认内存管理行为。
在一个对象的引用计数减为0时,与该对象对应的析构函数就会被调用。”
引用地址:
http://developer.51cto.com/art/201007/213585.htm
libxml2是一个很强大的处理XML文件的Python模块,通过C写成,这里介绍了一下基本的资料,安装,下载和基本指令,还有一个libxml2造成的内存泄露的处理方式。
libxml2是一个很强大的处理XML文件的Python模块,通过C写成,这里介绍了一下基本的资料,安装,下载和基本指令,还有一个libxml2造成的内存泄露的处理方式。
官方网址:
http://xmlsoft.org/
具体的下载地址,埋的很深,至少我花了一段时间才找到,这里直接给出win32下的Python模块下载地址:
http://xmlsoft.org/sources/win32/python/
根据自己的Python版本下载就行。
官方网站上给的操作信息是在少的可怜,只有单单一页的Python API介绍
http://xmlsoft.org/python.html
后来找了一些大神的博客才算零零碎碎的筹齐需要的知识点:
XPath (libxml2) in Python
http://ukchill.com/technology/getting-started-with-libxml2-and-python-part-1/
http://ukchill.com/technology/getting-started-with-libxml2-and-python-part-2/
这几就介绍一下最简单的操作:
import libxml2 doc = libxml2.parseFile(filename) #可以使用parseDoc代替parseFile,两者的区别是DOC处理已经读进进程的文件,File是能自己读取文件,所以只需要提供文件名。 ctxt = doc.xpathNewContext() record_nodes = ctxt.xpathEval('/*') #括号中的XPATH,这是寻找的是根目录下的所有NODE。 xpathEval寻找结果给出的是一个x列表,如xrange(10)生成的内容。 for node in record_nodes: name = node.name #node的名字 content = node.content #node的内容 sous-nodes = node.xpathEval('*') #node下面的子node,同处理根目录的原理一下进行处理。 ... #释放内存 if doc: doc.freeDoc()
由于libxml2在读取xml文本后不会自动释放内存,因此会出现内存泄露问题,这个困扰了我好久,一直以为是Python的程序问题,,找了一大堆Python程序的内存管理资料,但是最后才发现是libxml2的问题。所以上面代码中给出了释放内存的指令,非常非常重要!
ps python下管理内存模块gc
import gc a=['abc' for x in range(1000**5)] del a gc.collect()