WEB开发网
开发学院软件开发Python 可爱的 Python: Python 之优雅与瑕疵,第 1 部分 阅读

可爱的 Python: Python 之优雅与瑕疵,第 1 部分

 2008-09-30 12:57:47 来源:WEB开发网   
核心提示: 清单 10. 索引操作成功和失败的示例>>> r[4]4>>> i[4]TypeError: unindexable object对于每种序列/迭代器类型,只要费一番功夫,可爱的 Python: Python 之优雅与瑕疵,第 1 部分(8),总能够获得

清单 10. 索引操作成功和失败的示例

>>> r[4]
4
>>> i[4]
TypeError: unindexable object

对于每种序列/迭代器类型,只要费一番功夫,总能够获得其中的特定条目。一种方法是进行循环,直至到达所需的对象。另一种古怪的解决方案如下:

清单 11. 获得索引的怪方法

>>> thing, temp = itertools.tee(thing)
>>> zip(temp, '.'*5)[-1][0]
4

对 itertools.tee() 的预调用保留了原始迭代器。对于切片,可以按照特殊方式使用 itertools.islice() 函数。

清单 12. 获得一个切片的特殊方法

>>> r[4:9:2]
[4, 6, 8]
>>> list(itertools.islice(r,4,9,2)) # works for iterators
[4, 6, 8]

类包装器

为了方便起见,可以将这些技术组合成一个类包装器:

清单 13. 使迭代器可编制索引

>>> class Indexable(object):
...   def __init__(self, it):
...     self.it = it
...   def __getitem__(self, x):
...     self.it, temp = itertools.tee(self.it)
...     if type(x) is slice:
...       return list(itertools.islice(self.it, x.start, x.stop, x.step))
...     else:
...       return zip(temp, range(x+1))[-1][0]
...   def __iter__(self):
...     self.it, temp = itertools.tee(self.it)
...     return temp
...
>>> integers = Indexable(itertools.count())
>>> integers[4]
4
>>> integers[4:9:2]
[4, 6, 8]

所以,通过某些措施,可以让一个对象同时表现得像序列和迭代器。但是,费这么大力气实际上 应该是不必要的;无论涉及的是序列还是迭代器,编制索引和切片都应该是 “可行的”。

注意,Indexable 类包装器仍然不够灵活。主要问题是,每次都要创建迭代器的一个新副本。更好的方法应该是在对序列切片时缓存序列的头部,然后在以后访问已经检查的元素时使用所缓存的头部。当然,在使用迭代器时,要在占用的内存和速度之间有所取舍。但是,如果 Python 本身能够 “在幕后” 完成这些,就再好不过了 —— “高级用户” 可以对行为进行调优,而一般程序员应该不需要考虑这些。

在本系列的下一期中,我将讨论如何使用属性语法访问方法。

上一页  3 4 5 6 7 8 

Tags:可爱 Python Python

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接