蟒蛇文档测试与协程

问题描述:

我有一点麻烦doctest和协程...蟒蛇文档测试与协程

def coroutine(func): 
    def start(*args, **kwargs): 
     cr=func(*args, **kwargs) 
     cr.next() 
     return cr 
    start.__name__=func.__name__ 
    return start 

@coroutine 
def leader_tracking(): 
    """ 
    Tracks 'leader' status - only returns transitions 

    >>> lt=leader_tracking() 
    >>> print lt.send(False) 

    >>> print lt.send(False) 

    """ 
    last_status=False 
    result=("nop", None) 

    while True: 
     status=(yield result) 

     if status!=last_status: 
      direction="up" if last_status==False else "down" 
      last_status=status 
      result=("tr", direction) 
     else: 
      result=("nop", None) 

如果我使用通常的文档测试脚手架:

if __name__=="__main__": 
    import doctest 
    doctest.testmod() 

doctest没有显示任何东西,而如果我使用更蛮力的方法:

lt=leader_tracking() 
print lt.send(True) 
print lt.send(False) 
print lt.send(False) 
print lt.send(True) 
print lt.send(True) 
print lt.send(True) 
print lt.send(True) 
print lt.send(False) 

我可以看到预期的结果:

('tr', 'up') 
('tr', 'down') 
('nop', None) 
('tr', 'up') 
('nop', None) 
('nop', None) 
('nop', None) 
('tr', 'down') 

我在做什么毛病doctest

的文档测试模块着眼于它们被存储在一个函数的__doc__属性文档字符串。你的协同装饰只复制__name__,所以docstring会丢失,doctest找不到它。你可以手动指定__doc__属性,但更好的方法是使用functools模块:的func

import functools 

def coroutine(func): 
    @functools.wraps(func) 
    def start(*args, **kwargs): 
     cr = func(*args, **kwargs) 
     cr.next() 
     return cr 
    return start 

functools.wraps装饰拷贝所有的各种元数据属性到包装功能部件start,包括文档字符串,这样的doctest将按预期工作。

另外请注意,您的文档测试意见应包括预期的输出,以正常工作:

@coroutine 
def leader_tracking(): 
    """ 
    Tracks 'leader' status - only returns transitions 

    >>> lt=leader_tracking() 
    >>> print lt.send(True) 
    ('tr', 'up') 
    >>> print lt.send(False) 
    ('tr', 'down') 
    >>> print lt.send(False) 
    ('nop', None) 
    """ 
    last_status = False 
    result = ("nop", None) 

    while True: 
     status = yield result 

     if status != last_status: 
      direction = "up" if last_status == False else "down" 
      last_status = status 
      result = ("tr", direction) 
     else: 
      result = ("nop", None) 
+0

+1:了不起! – jldupont 2012-02-02 11:42:21