Displaying posts categorized under

Python

深入了解 Generator

原文作者:David Beazley 中文编译:Tony (digitalsatori) 第一部分:Iterators 和 Generators简介 Iteration 枚举 众所周知Python有一个“for”语句 你可以用它来在一组对象上做循环操作 >>> for x in [1, 4, 5, 10]: ... print x, ... 1 4 5 10 >>> 你不仅仅可以对list做循环枚举操作,还可以对很多不同类型的对象做相同的操作 对Dict的枚举 对字典进行循环枚举操作,会得到该字典的keys >>> prices = { 'GOOG' : 490.10, ... 'AAPL' : 145.23, ... 'YHOO' : 21.71 } ... >>> for key in prices: ... print [...]

Python食谱-1.25.在Unix终端上格式化显示HTML文本

原文作者:Brent Burley, Mark Moraes 中文翻译:Tony (digitalsatori) 问题 如何才能在Unix终端上显示HTML文本,使其可以表现粗体和下划线。 解决方案 最简单的方法是编制一个过滤脚本,从标准输入获取HTML然后在标准输出文本和终端控制符。因为本配方针对得唯一对象是Unix, 我们可以通过Unix命令 tput 来获取需要的终端控制符。具体方法是使用Python标准库中os模块中得popen函数来启动tput。 #!/usr/bin/env python import sys, os, htmllib, formatter # use Unix tput to get the escape sequences for bold, underline, reset set_bold = os.popen('tput bold').read( ) set_underline = os.popen('tput smul').read( ) perform_reset = os.popen('tput sgr0').read( ) class TtyFormatter(formatter.AbstractFormatter): ''' a formatter that keeps [...]

Python食谱-1.24.使指定的字符串忽略大小写

原文作者:Dale Strickland-Clark, Peter Cogolo, Mark McMahon 中文翻译:Tony (digitalsatori) 问题 如何才能使某些字符串在比较或查询时能忽略大小写,而在其它操作时能保持其原来的大小写? 解决方法 最佳的方案就是把这样需求的字符串封装在一个如下例所示的字符串的子类中: class iStr(str): """ 忽略大小写字符串类。 除了在比较和搜索时忽略大小写,其它与str的表现完全一样, """ def _ _init_ _(self, *args): self._lowered = str.lower(self) def _ _repr_ _(self): return '%s(%s)' % (type(self)._ _name_ _, str._ _repr_ _(self)) def _ _hash_ _(self): return hash(self._lowered) def lower(self): return self._lowered def _make_case_insensitive(name): ''' 将str中的一个方法改为忽略大小写后封装到iStr中。''' str_meth = [...]

Python食谱-1.23.Unicode数据编码输出到XML或HTML文件

原文作者:David Goodger, Peter Cogolo 中文翻译:Tony (digitalsatori) 问题 要将Uicode文本输出到HTML或是XML应用程序,且只能用较为流行但受限的编码比如:ASCII码,或Latin-1,如何操作? 解决方法 Python 有一个叫 xmlcharrefreplace 的编码出错处理器,它可以将选定编码之外的字符替换为XML数字字符参考(XML numeric characters references): def encode_for_xml(unicode_data, encoding='ascii'): return unicode_data.encode(encoding, 'xmlcharrefreplace') 上述的方法也可以用来处理HTML输出,但是我们希望能用HTML的‘符号实体‘(symbolic entity)。这样的话,我们就要自己定义一个函数并将其注册为编码错误处理函数。弄这么个函数其实并不难,因为Python标准库中已经有一个叫 htmlentitydefs 的模块,其包含了所有的HTML的实体定义。 import codecs from htmlentitydefs import codepoint2name def html_replace(exc): if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): s = [ u'&%s;' % codepoint2name[ord(c)] for c in exc.object[exc.start:exc.end] ] return ''.join(s), exc.end else: raise TypeError("can't [...]

Python食谱-1.22.将Unicode字符打印到标准输出

原文作者:David Ascher 中文翻译:Tony (digitalsatori) 问题 需要将Unicode字符打印到标准输出(比如在Debug时),但是它们不能使用默认的编码,怎么办? 解决方法 使用Python标准库中的 codecs 模块作为编码转换器来封装 sys.stdout (标准输出流)。比如我们的输出是到一个使用ISO-8859-1编码的终端,可以这样来写代码: import codecs, sys sys.stdout = codecs.lookup('iso8859-1')[-1](sys.stdout) 讨论 Unicode字符串处在一个足以容纳全世界所有语言所包含的字符的空间中。幸运的是,作为Unicode的使用者,我们不必了解Unicode字符串的内部表现方式。但是对于象 sys.stdout 这样的文件流,只能处理与特定编码关联的字节。我们可以改变Python的 site 模块来改变文件所使用的默认编码,但是这样的改变会全局影响Python ,使其它使用Python安装时的默认编码的程序出现混乱。(Python的默认标准编码是ASCII)。因此,我们不推荐这类改动。 本配方采用了一个更好的方法:将 sys.stdout 重新绑定到一个接收Unicode输入,以ISO-8859-1(也称为"Latin-1")编码输出的文件流。该方法并不会改变之前的 sys.stdout 的编码。首先我们保存当前的以ASCII为编码的 sys.stdout: >>> old = sys.stdout 然后,我们创建一个无法通过 sys.stdout 直接输出的Unicode字符串: >>> char = u"\N{LATIN SMALL LETTER A WITH DIAERESIS}" >>> print char Traceback (most recent call last): [...]

Python食谱-1.21.Unicode字符串和普通字符串的互换

原文作者:David Ascher, Paul Prescod 中文翻译:Tony (digitalsatori) 问题 如何处理超出ASCII码字符集的文本数据? 解决方法 Unicode字符串可以按照指定的编码方式转换为普通字符串: unicodestring = u"Hello world" # 将Unicode对象转换为字符串对象: "encode" utf8string = unicodestring.encode("utf-8") asciistring = unicodestring.encode("ascii") isostring = unicodestring.encode("ISO-8859-1") utf16string = unicodestring.encode("utf-16") # 将普通字符串对象转换为Unicode对象: "decode" plainstring1 = unicode(utf8string, "utf-8") plainstring2 = unicode(asciistring, "ascii") plainstring3 = unicode(isostring, "ISO-8859-1") plainstring4 = unicode(utf16string, "utf-16") assert plainstring1 == plainstring2 == plainstring3 == [...]

Python食谱-1.20.使用Unicode 处理国际化文本

原文作者:Holger Krekel 中文翻译:Tony (digitalsatori) 问题 如何处理包含'非ASCII'字符的文本字符串。 解决方法 在普通字节码字符串类型出现的地方都可以使用 Python 的first class Unicode类型。当你了解什么时候需要做字节码字符串和Unicode字符串之间的转换时,一切就变得容易了。 >>> german_ae = unicode('\xc3\xa4', 'utf8') 这里的german_ae是一个unicode字符串,表示德文字符"ae"-带有重音符号的小写字母a。它是用指定的UTF-8编码来解析字节码字符串 \xc3\xa4 而获得。字符编码方式有很多,但UTF-8是最经常被使用的。因为UTF-8可以为所有的Unicode字符串编码,同时又与7-bit ASCII码完全兼容(任何一个ASCII码字符串也同样是UTF-8编码的字符串)。 一旦突破了这个障碍,就自由了!我们可以象处理普通str字符串那样来处理Unicode字符串: >>> sentence = "This is a " + german_ae >>> sentence2 = "Easy!" >>> para = ". ".join([sentence, sentence2]) 注意这里的para是一个Unicode 字符串,因为当在字节码字符串和unicode字符串之间操作时,除了以下抛出异常的情况,总是会返回一个unicode字符串: >>> bytestring = '\xc3\xa4' # 非-ASCII码字符串 >>> german_ae += bytestring UnicodeDecodeError: 'ascii' [...]

Python食谱-1.19.判断字符串是否以多个字符串中的一个结尾

原文作者:Michele Simionato 中文翻译:Tony (digitalsatori) 问题 对于一个指定的字符串s,如何判断其是否以多个字符串中的任意一个结尾;或者说,有没有一个等效但更简洁明了的方法来表示 s.endwith(end1) or s.endwith(end2) or s.endwith(end3) ... 解决方法 itertools.imap 函数是解决此类问题简洁有效的方法: import itertools def anyTrue(predicate, sequence): return True in itertools.imap(predicate, sequence) def endsWith(s, *endings): return anyTrue(s.endswith, endings) 讨论 endsWith 的一个典型应用就是输出当前目录下的所有图片文件的名称: import os for filename in os.listdir('.'): if endsWith(filename, '.jpg', '.jpeg', '.gif'): print filename 本配方的解决方案中的通用处理方法同样适用与其它对字符串的检测判断。辅助函数 anyTrue 很通用,运行速度也快,我们可以传递任何'绑定方法‘(bound methods)给其第一个参数(predicate),比如: s.startwith` 或者 ``s.__contains__ 等等。实际上根本不使用 [...]

Python食谱-1.18.一次性替换字符串中的多个子串

原文作者:Xavier Defrang, Alex Martelli 中文翻译:Tony (digitalsatori) 问题 如何对一个字符串执行多个子串替换 解决方法 虽然用正则表达式来解决字符串替换的问题有时并不那么显而易见,但它们往往是最为便捷的方法。 re 对象(来自标准库中的 re 模块)强大的 sub 方法,使正则表达式在处理字符串替换时能得心应手。以下的函数返回一个新的字符串,该字符串将输入字符串中与字典的索引键匹配的子串替换为对应的字典值。 import re def multiple_replace(text, adict): rx = re.compile('|'.join(map(re.escape, adict))) def one_xlat(match): return adict[match.group(0)] return rx.sub(one_xlat, text) 讨论 本配方展示了如何通过Python标准库中的 re 模块来实现利用字典对一个字符串一次性执行多个子串替换的方法。在本例中,有一个基于字典的字符串映射规则。字典的索引键是希望被替换的字符串,对应的键值是用来替换的字符串。通常我们可以调用字符串对象的 replace 方法对字典中的每一对'键/值'执行替换操作,每一次的替换操作实际上都会创建一个新的字符串。如果能一次性的做所有的替换操作毫无疑问会更加理想,速度也会更快,因为这样的操作只创建一个新的字符串。 re.sub 的调用回调函数的用法使这种设想能轻松实现。 首先,我们为需要匹配并最终被替换的一系列的索引键创建一个正则表达式。这个正则表达式具有 a1|a2|...|aN 这种模式,它们是由N个将要被替换的字串用竖线连接组成,在配方中用一行代码生成。然后,我们给 re.sub 传递一个回调函数作为参数(而不是传递一个替换字符串)。 re.sub 会在每次匹配时调用这个函数,并将 re.MatchObject 实例作为该函数的参数。这个函数返回的值将作为 re.sub 匹配对象的替换字符串。在本例中回调函数在字典中搜索匹配字串,并将对应的值返回。 本配方中的 multiple_replace 函数会在每次调用它时重新计算正则表达式,重新定义 one_xlat [...]

Python食谱-1.17.Python2.4中解析替换字符串中的变量

原文作者:John Nielsen, Lawrence Oluyede, Nick Coghlan 中文编译:Tony (digitalsatori) 问题 使用Python2.4,我们如何才能用简单的方法做到将字符串中特殊标记的标示符用字典中标示符所对应的值来替代呢? 解决方法 Python2.4中的 string.Template 可以用来处理此类问题,以下说明如何使用该类: import string # 创建字符串模板用 $ 符号标记标示符 new_style = string.Template('this is $thing') # 使用 template 的 substitute 方法,用一个匹配字典作为其参数 print new_style.substitute({'thing':5}) # 输出: this is 5 print new_style.substitute({'thing':'test'}) # 输出: this is test # 你也可以用键-值对来处理替换对象 print new_style.substitute(thing=5) # 输出: this is 5 print [...]