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 ...
随机推荐
- Linux内核设计基础(十)之内核开发与总结
(1)Linux层次结构: (2)Linux内核组成: 主要由进程调度(SCHED).内存管理(MM).虚拟文件系统(VFS).网络接口(NET)和进程间通信(IPC)等5个子系统组成. (3)与Un ...
- Dynamics CRM 2016 使用Plug-in Trace Log调试插件
1.写插件 首先,让我们写一个简单的插件来测试新插件跟踪日志功能.请注意,在下面的示例代码中,我们增加ITracingService的一个实例,以及记录有关插件的执行信息记录的一些键值: 2.注册插件 ...
- 注册AxtiveX控件
Win8.1或者Win7下 首先在“管理员的身份”运行cmd 然后输入:regsvr32 D:\***\*.ocx
- 卸载rpm包提示:error: specifies multiple packages
–allmatches Remove all versions of the package which match PACKAGE_NAME. Normally an error is issue ...
- 无法从带有索引像素格式的图像创建graphics对象(转)
大家在用 .NET 做图片水印功能的时候, 很可能会遇到 “无法从带有索引像素格式的图像创建graphics对象”这个错误,对应的英文错误提示是“A Graphics object cannot be ...
- Eclipse搭建Android开发环境(安装ADT,Android4.4.2)(转)
使用Eclipse做Android开发,需要先在Eclipse上安装ADT(Android Development Tools)插件. 1.安装JDK 1.7 JDK官网http://www.orac ...
- Asp.net实现在线人数统计功能代码实例
application最经典的一个方法:统计在线人数,这需要借助于我们的全局应用程序类来对登录的用户信息进行统计: 以下是代码片段: void application_start(object ...
- FpSpread添加表头(列名)标注
for (int j = 0; j < fp.ActiveSheetView.ColumnCount; j++) { fp.ActiveSheetView.ColumnHeader.Cells[ ...
- IE6 浏览器常见兼容问题 大汇总(23个)
IE6以及各个浏览器常见兼容问题 大汇总 综述:虽然说IE6在2014年4月将被停止支持,但是不得不说的是,IE6的市场并不会随着支持的停止而立刻消散下去,对于WEB前端开发工程师来说,兼容IE6 兼 ...
- ORACLE触发器概述之【行触发器】【weber出品】
1. 行触发器的定义 行触发器是指执行DML操作时,每作用一行就触发一次的触发器.审计数据变化时,可以使用行触发器 2. 建立行触发器的语法如下: create or replace trigger ...