BEEN
life‘s short
日历
二月 | ||||||
---|---|---|---|---|---|---|
日 | 一 | 二 | 三 | 四 | 五 | 六 |
28 | 29 | 30 | 31 | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 1 | 2 |
最新评论
最新留言
链接
python 执行过程
2014年2月23日 16:17 | Comments(4) | Category:python | Tags:
参考资料
Dive into python
在Dive into python第五章中有一个提取MP3信息的脚本,不是很理解现在整理一下思路
"""Framework for getting filetype-specific metadata. Instantiate appropriate class with filename. Returned object acts like a dictionary, with key-value pairs for each piece of metadata. import fileinfo info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3") print "\\n".join(["%s=%s" % (k, v) for k, v in info.items()]) Or use listDirectory function to get info on all files in a directory. for info in fileinfo.listDirectory("/music/ap/", [".mp3"]): ... Framework can be extended by adding classes for particular file types, e.g. HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for parsing its files appropriately; see MP3FileInfo for example. This program is part of "Dive Into Python", a free Python book for experienced programmers. Visit http://diveintopython.org/ for the latest version. """ __author__ = "Mark Pilgrim (mark@diveintopython.org)" __version__ = "$Revision: 1.3 $" __date__ = "$Date: 2004/05/05 21:57:19 $" __copyright__ = "Copyright (c) 2001 Mark Pilgrim" __license__ = "Python" import os import sys from UserDict import UserDict def stripnulls(data): "strip whitespace and nulls" return data.replace("\00", " ").strip() class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} def __parse(self, filename): "parse ID3v1.0 tags from MP3 file" self.clear() try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() if tagdata[:3] == 'TAG': for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end]) except IOError: pass def __setitem__(self, key, item): if key == "name" and item: self.__parse(item) FileInfo.__setitem__(self, key, item) def listDirectory(directory, fileExtList): "get list of file info objects for files of particular extensions" fileList = [os.path.normcase(f) for f in os.listdir(directory)] fileList = [os.path.join(directory, f) for f in fileList \ if os.path.splitext(f)[1] in fileExtList] def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] return hasattr(module, subclass) and getattr(module, subclass) or FileInfox return [getFileInfoClass(f)(f) for f in fileList] if __name__ == "__main__": for info in listDirectory("/home/been/Desktop/", [".mp3"]): print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) print
用户执行代码从这里开始
if __name__ == "__main__": for info in listDirectory("/home/been/Desktop/", [".mp3"]):
一个for循环代码跳到了自定义的function上
def listDirectory(directory, fileExtList): "get list of file info objects for files of particular extensions" fileList = [os.path.normcase(f) for f in os.listdir(directory)] """这里返回在目录directory下的所有文件,文件夹的小写名称到fielList""" fileList = [os.path.join(directory, f) for f in fileList \ if os.path.splitext(f)[1] in fileExtList] """这里返回的是所有带地址的mp3格式的文件名,如/home/been/Desktop/wake me up.mp3""" def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] """subclass 的内容是MP3FileInfo""" return hasattr(module, subclass) and getattr(module, subclass) or FileInfox """hastter()和getatter()是检查subclass这个模块是否可用,是就返回hasatter()否则返回FileInfo 不过这里不仅仅是返回那么简单,同时还是调用了MP3FileInfo这个模块""" return [getFileInfoClass(f)(f) for f in fileList]
python执行代码到这里
class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)}
MP3FileInfo从FileInfo中继承了它的方法,代码又跑到了这里
class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename
同样FileInfo又从UserDict中继承了它的方法,UserDict是一个python自定义的class,用来创建字典的类。
可以用pydoc UserDict查看它的方法和属性。可以在/usr/lib/python2.7/UserDict.py 查看源代码
这部分代码生成了一个字典{filename:none}
接着代码回到了这里
class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} def __parse(self, filename): "parse ID3v1.0 tags from MP3 file" self.clear() try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() if tagdata[:3] == 'TAG': for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end]) except IOError: pass def __setitem__(self, key, item): if key == "name" and item: self.__parse(item) FileInfo.__setitem__(self, key, item)
在这里代码首先在__setitem__执行,疑问出来了书上说__setitem__是被MP3FileInfo覆盖的,但是__setitem__()却要和父类UserDict中的__setitem__()的参数的个数要一样。下面这两个是为了解决临界问题
当首次执行__setitem__时key为not defined,item在__parse已经创建。理解if这一句需要知道== and的优先顺序,这一句的意思是:如果key=="name"则执行self.__parse(item)否则执行File~。
因为FileInfo没有__setitem__类,因此需要到父类UserDict中去找。到这里所有的信息都存在了FileInfo字典中。
最后的代码
if __name__ == "__main__": for info in listDirectory("/home/been/Desktop/", [".mp3"]): print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) print
for语句这里的info in ListDirectory(),相当于info=MP3FileInfo(),所以info有info.items()属性
后记:把博文写出来的确是对代码理解透彻了很多,因为只学过c,对类这种编程思想跟本没有了解过,一直在纠结干嘛要创建字典,是怎么通过类给字典里的key:value赋值,是怎么提取里面的元素的
补充python运算符的优先顺序:从上往下递增
运算符 | 描述 |
---|---|
lambda | Lambda表达式 |
or | 布尔“或” |
and | 布尔“与” |
not x | 布尔“非” |
in,not in | 成员测试 |
is,is not | 同一性测试 |
<,<=,>,>=,!=,== | 比较 |
| | 按位或 |
^ | 按位异或 |
& | 按位与 |
<<,>> | 移位 |
+,- | 加法与减法 |
*,/,% | 乘法、除法与取余 |
+x,-x | 正负号 |
~x | 按位翻转 |
** | 指数 |
x.attribute | 属性参考 |
x[index] | 下标 |
x[index:index] | 寻址段 |
f(arguments...) | 函数调用 |
(experession,...) | 绑定或元组显示 |
[expression,...] | 列表显示 |
{key:datum,...} | 字典显示 |
'expression,...' | 字符串转换 |
代码执行过程
2014年2月23日 13:26 | Comments(1) | Category:python | Tags:
参考资料:
Dive into python
Dive into python 第五章中的有一个脚本,是提取MP3文件中的信息的。一直很不理解,现在希望整理一下思路
"""Framework for getting filetype-specific metadata. Instantiate appropriate class with filename. Returned object acts like a dictionary, with key-value pairs for each piece of metadata. import fileinfo info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3") print "\\n".join(["%s=%s" % (k, v) for k, v in info.items()]) Or use listDirectory function to get info on all files in a directory. for info in fileinfo.listDirectory("/music/ap/", [".mp3"]): ... Framework can be extended by adding classes for particular file types, e.g. HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for parsing its files appropriately; see MP3FileInfo for example. This program is part of "Dive Into Python", a free Python book for experienced programmers. Visit http://diveintopython.org/ for the latest version. """ __author__ = "Mark Pilgrim (mark@diveintopython.org)" __version__ = "$Revision: 1.3 $" __date__ = "$Date: 2004/05/05 21:57:19 $" __copyright__ = "Copyright (c) 2001 Mark Pilgrim" __license__ = "Python" import os import sys from UserDict import UserDict def stripnulls(data): "strip whitespace and nulls" return data.replace("\00", " ").strip() class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} def __parse(self, filename): "parse ID3v1.0 tags from MP3 file" self.clear() try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() if tagdata[:3] == 'TAG': for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end]) except IOError: pass def __setitem__(self, key, item): if key == "name" and item: self.__parse(item) FileInfo.__setitem__(self, key, item) def listDirectory(directory, fileExtList): "get list of file info objects for files of particular extensions" fileList = [os.path.normcase(f) for f in os.listdir(directory)] fileList = [os.path.join(directory, f) for f in fileList \ if os.path.splitext(f)[1] in fileExtList] def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] return hasattr(module, subclass) and getattr(module, subclass) or FileInfox return [getFileInfoClass(f)(f) for f in fileList]
if __name__ == "__main__": for info in listDirectory("/home/been/Desktop/", [".mp3"]):
print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) print
用户执行脚本,到达这里