cStringIO模块例子
# Vorbis comment support for Mutagen
# Copyright 2005-2006 Joe Wreschnig
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
"""Read and write Vorbis comment data.
Vorbis comments are freeform key/value pairs; keys are
case-insensitive ASCII and values are Unicode strings. A key may have
multiple values.
The specification is at http://www.xiph.org/vorbis/doc/v-comment.html.
"""
import sys
from cStringIO import StringIO
import mutagen
from mutagen._util import DictMixin, cdata
try: set
except NameError:
from sets import Set as set
def is_valid_key(key):
"""Return true if a string is a valid Vorbis comment key.
Valid Vorbis comment keys are printable ASCII between 0x20 (space)
and 0x7D ('}'), excluding '='.
"""
for c in key:
if c < " " or c > "}" or c == "=": return False
else: return bool(key)
istag = is_valid_key
class error(IOError): pass
class VorbisUnsetFrameError(error): pass
class VorbisEncodingError(error): pass
class VComment(mutagen.Metadata, list):
"""A Vorbis comment parser, accessor, and renderer.
All comment ordering is preserved. A VComment is a list of
key/value pairs, and so any Python list method can be used on it.
Vorbis comments are always wrapped in something like an Ogg Vorbis
bitstream or a FLAC metadata block, so this loads string data or a
file-like object, not a filename.
Attributes:
vendor -- the stream 'vendor' (i.e. writer); default 'Mutagen'
"""
vendor = u"Mutagen " + mutagen.version_string
def __init__(self, data=None, *args, **kwargs):
# Collect the args to pass to load, this lets child classes
# override just load and get equivalent magic for the
# constructor.
if data is not None:
if isinstance(data, str):
data = StringIO(data)
elif not hasattr(data, 'read'):
raise TypeError("VComment requires string data or a file-like")
self.load(data, *args, **kwargs)
def load(self, fileobj, errors='replace', framing=True):
"""Parse a Vorbis comment from a file-like object.
Keyword arguments:
errors:
'strict', 'replace', or 'ignore'. This affects Unicode decoding
and how other malformed content is interpreted.
framing -- if true, fail if a framing bit is not present
Framing bits are required by the Vorbis comment specification,
but are not used in FLAC Vorbis comment blocks.
"""
try:
vendor_length = cdata.uint_le(fileobj.read(4))
self.vendor = fileobj.read(vendor_length).decode('utf-8', errors)
count = cdata.uint_le(fileobj.read(4))
for i in range(count):
length = cdata.uint_le(fileobj.read(4))
try: string = fileobj.read(length).decode('utf-8', errors)
except (OverflowError, MemoryError):
raise error("cannot read %d bytes, too large" % length)
try: tag, value = string.split('=', 1)
except ValueError, err:
if errors == "ignore":
continue
elif errors == "replace":
tag, value = u"unknown%d" % i, string
else:
raise VorbisEncodingError, str(err), sys.exc_info()[2]
try: tag = tag.encode('ascii', errors)
except UnicodeEncodeError:
raise VorbisEncodingError, "invalid tag name %r" % tag
else:
if is_valid_key(tag): self.append((tag, value))
if framing and not ord(fileobj.read(1)) & 0x01:
raise VorbisUnsetFrameError("framing bit was unset")
except (cdata.error, TypeError):
raise error("file is not a valid Vorbis comment")
def validate(self):
"""Validate keys and values.
Check to make sure every key used is a valid Vorbis key, and
that every value used is a valid Unicode or UTF-8 string. If
any invalid keys or values are found, a ValueError is raised.
"""
if not isinstance(self.vendor, unicode):
try: self.vendor.decode('utf-8')
except UnicodeDecodeError: raise ValueError
for key, value in self:
try:
if not is_valid_key(key): raise ValueError
except: raise ValueError("%r is not a valid key" % key)
if not isinstance(value, unicode):
try: value.encode("utf-8")
except: raise ValueError("%r is not a valid value" % value)
else: return True
def clear(self):
"""Clear all keys from the comment."""
del(self[:])
def write(self, framing=True):
"""Return a string representation of the data.
Validation is always performed, so calling this function on
invalid data may raise a ValueError.
Keyword arguments:
framing -- if true, append a framing bit (see load)
"""
self.validate()
f = StringIO()
f.write(cdata.to_uint_le(len(self.vendor.encode('utf-8'))))
f.write(self.vendor.encode('utf-8'))
f.write(cdata.to_uint_le(len(self)))
for tag, value in self:
comment = "%s=%s" % (tag, value.encode('utf-8'))
f.write(cdata.to_uint_le(len(comment)))
f.write(comment)
if framing: f.write("\x01")
return f.getvalue()
def pprint(self):
return "\n".join(["%s=%s" % (k.lower(), v) for k, v in self])
class VCommentDict(VComment, DictMixin):
"""A VComment that looks like a dictionary.
This object differs from a dictionary in two ways. First,
len(comment) will still return the number of values, not the
number of keys. Secondly, iterating through the object will
iterate over (key, value) pairs, not keys. Since a key may have
multiple values, the same value may appear multiple times while
iterating.
Since Vorbis comment keys are case-insensitive, all keys are
normalized to lowercase ASCII.
"""
def __getitem__(self, key):
"""A list of values for the key.
This is a copy, so comment['title'].append('a title') will not
work.
"""
key = key.lower().encode('ascii')
values = [value for (k, value) in self if k.lower() == key]
if not values: raise KeyError, key
else: return values
def __delitem__(self, key):
"""Delete all values associated with the key."""
key = key.lower().encode('ascii')
to_delete = filter(lambda x: x[0].lower() == key, self)
if not to_delete:raise KeyError, key
else: map(self.remove, to_delete)
def __contains__(self, key):
"""Return true if the key has any values."""
key = key.lower().encode('ascii')
for k, value in self:
if k.lower() == key: return True
else: return False
def __setitem__(self, key, values):
"""Set a key's value or values.
Setting a value overwrites all old ones. The value may be a
list of Unicode or UTF-8 strings, or a single Unicode or UTF-8
string.
"""
key = key.lower().encode('ascii')
if not isinstance(values, list):
values = [values]
try: del(self[key])
except KeyError: pass
for value in values:
self.append((key, value))
def keys(self):
"""Return all keys in the comment."""
return self and list(set([k.lower() for k, v in self]))
def as_dict(self):
"""Return a copy of the comment data in a real dict."""
return dict((key, self[key]) for key in self.keys())
cStringIO模块例子的更多相关文章
- python标准库介绍——20 cStringIO 模块详解
==cStringIO 模块== ``cStringIO`` 是一个可选的模块, 是 ``StringIO`` 的更快速实现. 它的工作方式和 ``StringIO`` 基本相同, 但是它不可以被继承 ...
- Python random模块 例子
最近用到随机数,就查询资料总结了一下Python random模块(获取随机数)常用方法和使用例子. 1.random.random random.random()用于生成一个0到1的随机符点数: ...
- StringIO 模块用于在内存缓冲区中读写数据
模块是用类编写的,只有一个StringIO类,所以它的可用方法都在类中.此类中的大部分函数都与对文件的操作方法类似. 例: #coding=gbk import StringIO s=StringIO ...
- python 各模块
01 关于本书 02 代码约定 03 关于例子 04 如何联系我们 1 核心模块 11 介绍 111 内建函数和异常 112 操作系统接口模块 113 类型支持模块 114 正则表达式 115 语言支 ...
- Python进阶之模块
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...
- 学习Python:StringIO与cStringIO
StringIO的行为与file对象非常像,但它不是磁盘上文件,而是一个内存里的“文件”,我们可以将操作磁盘文件那样来操作StringIO.一个简单的例子,让你对StringIO有一个感性的认识: f ...
- python PIL Image模块
原地址:http://hi.baidu.com/drunkdream/item/9c9ac638dfc46ec6382ffac5 实验环境: windows7+python2.6+pycrust+PI ...
- day--6_python常用模块
常用模块: time和datetime shutil模块 radom string shelve模块 xml处理 configparser处理 hashlib subprocess logging模块 ...
- Poco C++库网络模块例子解析2-------HttpServer
//下面程序取自 Poco 库的Net模块例子----HTTPServer 下面开始解析代码 #include "Poco/Net/HTTPServer.h" //继承自TCPSe ...
随机推荐
- Windows下命令行直接编译程序
D:\> cl hello.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86 Cop ...
- unity的坑
http://dearymz.blog.163.com/blog/static/20565742013341916919/ 编辑器: Hierarchy窗口中是场景中的Game Object列表 Pr ...
- 数据库备份和恢复秩序的关系(周围环境:Microsoft SQL Server 2008 R2)
让我们来看看在备份序列新手 --1.塔建环境(生成测试数据和备份文件) /* 測试环境: Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) ...
- JavaScript函数 bind call apply区别
1. apply calll 在JavaScript中 call 和 apply 都是为了改变某个函数运行时上下文而存在的, 换句话说就是为了改变函数内部的this的指向. 这里我们有一个新的对象 b ...
- 黑马程序员——String类
------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...
- memcached session共享
http://www.baidu.com/s?wd=memcached%20session%E5%85%B1%E4%BA%AB&rsv_spt=1&issp=1&f=8& ...
- Jquery:Jquery中的DOM操作<二>
由于昨天晚上回来的晚,写的有点匆忙,所以昨天的学习笔记中出现了多处错误的地方,幸好有各位园友帮忙指出,在这里谢过各位了!今天继续学习关于Jquery中DOM的操作,其实是昨天随笔的延续,求围观!!! ...
- Java关键字transient和volatile
transient标记的变量,在进行序列化的时候,这个字段不进行序列化操作. volatile标记的变量,在进行读写时,必须强制的与内存同步,即在读的时候需要从内存中读取,写的时候也需要回写到内存中. ...
- OOM总结
本文主要信息是来自互联网,我只是自己做了一点总结和摘要. OOM发生的原因 简单的说通过不同的内存分配方式对不同的对象进行操作,会因为android系统版本的差异而产生不同的行为.主要是2.0和4.0 ...
- linux下mysql环境支持中文配置步骤
sql脚本执行前加上: CREATE DATABASE IF NOT EXISTS mydatabase DEFAULT CHARSET utf8 COLLATE UTF8_GENERAL_CI; u ...