1

我在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)

如果我使用通常的 doctest 脚手架:

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

4

1 回答 1

6

doctest 模块查看存储在__doc__函数属性中的文档字符串。您的协程装饰器仅复制__name__,因此文档字符串会丢失并且 doctest 找不到它。您可以手动分配__doc__属性,但更好的方法是使用 functools 模块:

import functools

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

装饰器将functools.wraps所有各种元数据属性复制func到包装函数start中,包括文档字符串,以便 doctest 按预期工作。

另请注意,您的 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)
于 2012-02-02T03:56:30.610 回答