Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Pythonic拾趣

$
0
0
Beautiful is better than ugly.

by Tim Peters

以下是本人在学习python过程中总结的一些Python实践、技巧、思路。此文档将不断更新。

迭代器实现 class Reverse(object): def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def next(self): if self.index == 0: raise StopIteration self.index -= 1 return self.data[self.index] for iter in Reverse("Hello, World."): pass

定义一个 __iter__() 方法,它返回一个有 next() 方法的对象,如果类本身定义了 next() , __iter__() 直接返回 self 。

请注意可迭代对象和迭代器对象的区别,上面这个例子中,Reverse即是可迭代对象,也是迭代器对象。而诸如 dict , list 是可迭代对象,而要获取它们的迭代器对象,则需要使用 iter(o) 函数。

除此之外,还可以用生成器实现迭代器。因为生成器自带了 __iter__ 和 next ,所以写出来的代码非常紧凑。理解生成器的关键是要理解 yeild ,以下是我对 yeild 的理解。

def Reverse(data): for index in range(len(data) - 1, -1, -1): yield data[index] r = Reverse("hello") # r 是一个生成器 r.next() # 执行next时,Reverse开始执行,并且执行到yield 这句停止,并把yield后面的参数作为r.next()的 返回值。 r.next() # 从yield的下一句开始执行,上一次的局部状态和执行状态也恢复了。 属性字典

属性字典相比 dict 并没有什么特别的含义,仅仅是让代码看起来更优雅大方。在web.py框架里面的实现如下:

class Dict(dict): def __getattr__(self, key): try: return self[key] except KeyError, k: raise AttributeError, k def __setattr__(self, key, value): self[key] = value def __delattr__(self, key): try: del self[key] except KeyError, k: raise AttributeError, k def __repr__(self): return '<Dict ' + dict.__repr__(self) + '>' 字符编码问题

Python 中有两种由 basestring 派生而来的字符串类型, str 和 unicode , str 在内存中说白了就是一串字节序列,如果迭代str的话,则是按一个字节一个字节迭代的,它并不关心字节序列所采用的编码格式。而 unicode 则是一个 unicode 对象。由于各种编码格式都可以转成 unicode 编码,所以通常用 unicode 作为中间编码,也即 A编码 decode 成 unicode , unicode encode 成B编码。

Python文件的默认编码是 ascii ,当我们运行一个Python文件时,Python解析器会按照 ascii 编码去读取该文件,假如文件中有些中文字符,由于 ascii 编码中没有,就会报语法错误。此时我们需要修改Python文件的编码,也即在文件头加上如下代码:

# coding=utf8

Python最佳实践上建议从文件或者网络上读取的 str 都转成 unicode ,然后在写出时(比如写到文件或者http 响应),转成对应的目标编码格式。但我在实际编程学习中,发现很多库函数的入参,并不支持 unicode 字符串,所以我一般在读入时,先将 str 的编码转成 utf8 ,代码如下:

def safestr(obj, encoding='utf-8'): if isinstance(obj, unicode): return obj.encode(encoding) elif isinstance(obj, str): return obj elif hasattr(obj, 'next'): # iterator return itertools.imap(safestr, obj) else: return str(obj)

同样,将 utf8 转换成 unicode 的代码如下:

def safeunicode(obj, encoding='utf-8'): t = type(obj) if t is unicode: return obj elif t is str: return obj.decode(encoding) elif t in [int, float, bool]: return unicode(obj) elif hasattr(obj, '__unicode__') or isinstance(obj, unicode): return unicode(obj) else: return str(obj).decode(encoding) 装饰器实现 metaclass的本质 字典排序

dict 这个数据结构在 Python 里面是由哈希表实现的,我们可以利用 sorted 函数来对 dict 排序。


Viewing all articles
Browse latest Browse all 9596

Trending Articles