如何在 python 中使用带有修饰函数的 doctest?

Posted

技术标签:

【中文标题】如何在 python 中使用带有修饰函数的 doctest?【英文标题】:How to use doctest with a decorated function in python? 【发布时间】:2014-06-28 09:24:55 【问题描述】:

我正在使用装饰器:

class Memoized(object):

    __cache = 

    def __init__(self, func):
        self.func = func
        key = (func.__module__, func.__name__)
        # print key
        if key not in self.__cache:
            self.__cache[key] = 
        self.mycache = self.__cache[key]

    def __call__(self, *args):
        try:
            return self.mycache[args]
        except KeyError:
            value = self.func(*args)
            self.mycache[args] = value
            return value
        except TypeError:
            return self.func(*args)

    def __get__(self, obj, objtype):
       return functools.partial(self.__call__, obj)

    def reset(self):
        for v in self.__cache.itervalues():
            v.clear()

还有一个功能:

@Memoized
def is_tile_inside_border(x, y, z, border):
    '''Checks if a tile is inside border or not
    >>> is_tile_inside_border(85,53,7,'iran')
    3
    >>> is_tile_inside_border(85,15,7,'iran')
    0
    '''
    binary_data = get_border_binary(border, z)
    return isInside((x, y), binary_data)

但是当使用 doctest 模块时(python mycode.py -v):

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

Python 在 doc-string 中找不到测试。我知道这是装饰器的问题。但是我该如何解决呢?

PS:functools.update_wrapper(self, func) 不工作!

【问题讨论】:

你试过functools.wraps装饰器吗? ***.com/questions/308999/what-does-functools-wraps-do relevant ticket @AndrewGorcester 我研究了链接,谢谢。但是我很想知道如何在装饰器类中使用 wraps 【参考方案1】:

我们如何通过使用memo 装饰器来回避这个问题,它返回一个函数而不是类实例:

import functools

def decorator(d):
    """Make function d a decorator: d wraps a function fn.
    Authors: Peter Norvig and Darius Bacon"""
    def _d(fn):
        return functools.update_wrapper(d(fn), fn)
    functools.update_wrapper(_d, d)
    return _d

@decorator
def memo(f):
    # by Peter Norvig
    """Decorator that caches the return value for each call to f(args).
    Then when called again with same args, we can just look it up."""
    cache = 

    def _f(*args):
        try:
            return cache[args]
        except KeyError:
            cache[args] = result = f(*args)
            return result
        except TypeError:
            # some element of args can't be a dict key
            return f(*args)
    _f.cache = cache
    return _f

@memo
def is_tile_inside_border(x, y, z, border):
    '''Checks if a tile is inside border or not
    >>> is_tile_inside_border(85,53,7,'iran')
    3
    >>> is_tile_inside_border(85,15,7,'iran')
    0
    '''
    # binary_data = get_border_binary(border, z)
    # return isInside((x, y), binary_data)
    return True

class Foo(object):
    @memo
    def bar(self, x):
        """
        >>> Foo().bar(1)
        2
        """
        return x

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

【讨论】:

以上是关于如何在 python 中使用带有修饰函数的 doctest?的主要内容,如果未能解决你的问题,请参考以下文章

Python 修饰函数中的参数如何工作

Python OOP-4

使用 User32.dll SendMessage 发送带有 ALT 修饰符的键 [重复]

python函数修饰器(decorator)

如何将函数中的多个修饰符应用于 SwiftUI 中的给定视图?

Python函数修饰符@的使用