2012-02-02 5 views
1

Я имею немного неприятности с doctest и сопрограммам ...питон 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?

ответ

6

Модуль doctest смотрит на docstrings, которые хранятся в атрибуте функции __doc__. Ваш корректор coroutine копирует только __name__, поэтому docstring теряется, и 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 

The 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) 
+0

+1: изумительно !! – jldupont

 Смежные вопросы

  • Нет связанных вопросов^_^