============================ 4.4 实现è¿ä»£å™¨åè®® ============================ ---------- 问题 ---------- ä½ æƒ³æž„å»ºä¸€ä¸ªèƒ½æ”¯æŒè¿ä»£æ“作的自定义对象,并希望找到一个能实现è¿ä»£å议的简å•æ–¹æ³•ã€‚ ---------- 解决方案 ---------- ç›®å‰ä¸ºæ¢ï¼Œåœ¨ä¸€ä¸ªå¯¹è±¡ä¸Šå®žçŽ°è¿ä»£æœ€ç®€å•çš„æ–¹å¼æ˜¯ä½¿ç”¨ä¸€ä¸ªç”Ÿæˆå™¨å‡½æ•°ã€‚ 在4.2å°èŠ‚ä¸ï¼Œä½¿ç”¨Nodeç±»æ¥è¡¨ç¤ºæ ‘形数æ®ç»“æž„ã€‚ä½ å¯èƒ½æƒ³å®žçŽ°ä¸€ä¸ªä»¥æ·±åº¦ä¼˜å…ˆæ–¹å¼éåŽ†æ ‘å½¢èŠ‚ç‚¹çš„ç”Ÿæˆå™¨ã€‚ 下é¢æ˜¯ä»£ç 示例: .. code-block:: python class Node: def __init__(self, value): self._value = value self._children = [] def __repr__(self): return 'Node({!r})'.format(self._value) def add_child(self, node): self._children.append(node) def __iter__(self): return iter(self._children) def depth_first(self): yield self for c in self: yield from c.depth_first() # Example if __name__ == '__main__': root = Node(0) child1 = Node(1) child2 = Node(2) root.add_child(child1) root.add_child(child2) child1.add_child(Node(3)) child1.add_child(Node(4)) child2.add_child(Node(5)) for ch in root.depth_first(): print(ch) # Outputs Node(0), Node(1), Node(3), Node(4), Node(2), Node(5) 在这段代ç ä¸ï¼Œ``depth_first()`` 方法简å•ç›´è§‚。 它首先返回自己本身并è¿ä»£æ¯ä¸€ä¸ªå节点并 通过调用å节点的 ``depth_first()`` 方法(使用 ``yield from`` è¯å¥)è¿”å›žå¯¹åº”å…ƒç´ ã€‚ ---------- 讨论 ---------- Pythonçš„è¿ä»£åè®®è¦æ±‚一个 ``__iter__()`` 方法返回一个特殊的è¿ä»£å™¨å¯¹è±¡ï¼Œ 这个è¿ä»£å™¨å¯¹è±¡å®žçŽ°äº† ``__next__()`` 方法并通过 ``StopIteration`` å¼‚å¸¸æ ‡è¯†è¿ä»£çš„完æˆã€‚ 但是,实现这些通常会比较ç¹ç。 下é¢æˆ‘们演示下这ç§æ–¹å¼ï¼Œå¦‚何使用一个关è”è¿ä»£å™¨ç±»é‡æ–°å®žçŽ° ``depth_first()`` 方法: .. code-block:: python class Node2: def __init__(self, value): self._value = value self._children = [] def __repr__(self): return 'Node({!r})'.format(self._value) def add_child(self, node): self._children.append(node) def __iter__(self): return iter(self._children) def depth_first(self): return DepthFirstIterator(self) class DepthFirstIterator(object): ''' Depth-first traversal ''' def __init__(self, start_node): self._node = start_node self._children_iter = None self._child_iter = None def __iter__(self): return self def __next__(self): # Return myself if just started; create an iterator for children if self._children_iter is None: self._children_iter = iter(self._node) return self._node # If processing a child, return its next item elif self._child_iter: try: nextchild = next(self._child_iter) return nextchild except StopIteration: self._child_iter = None return next(self) # Advance to the next child and start its iteration else: self._child_iter = next(self._children_iter).depth_first() return next(self) ``DepthFirstIterator`` 类和上é¢ä½¿ç”¨ç”Ÿæˆå™¨çš„版本工作原ç†ç±»ä¼¼ï¼Œ 但是它写起æ¥å¾ˆç¹çï¼Œå› ä¸ºè¿ä»£å™¨å¿…须在è¿ä»£å¤„ç†è¿‡ç¨‹ä¸ç»´æŠ¤å¤§é‡çš„状æ€ä¿¡æ¯ã€‚ å¦ç™½æ¥è®²ï¼Œæ²¡äººæ„¿æ„写这么晦涩的代ç ã€‚å°†ä½ çš„è¿ä»£å™¨å®šä¹‰ä¸ºä¸€ä¸ªç”Ÿæˆå™¨åŽä¸€åˆ‡è¿Žåˆƒè€Œè§£ã€‚