doctest exec using python ./file.py -v

doctest

using

python ./export.py -v

verbose args show the test detail good for u

 

 

Python doctest - 朝着梦想 渐行前进 - 博客频道 - youkuaiyun.com

Python doctest

分类: Python 481人阅读 评论(0) 收藏 举报
>>> def median(pool):
    '''Statistical median to demonstrate doctest.
    >>> median([2, 9, 9, 7, 9, 2, 4, 5, 8])
    7
    ''' #代码的文档,功能说明。如果运行以上参数,期望结果是7
    copy = sorted(pool)
    size = len(copy)
    if size % 2 == 1:
        return copy[(size-1)/2]
    else :
        return (copy[size/2-1] + copy[size/2])/2

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

运行结果:
TestResults(failed=0, attempted=1)
如果我把上面的7改为8,运行结果如下:
**********************************************************************
File "__main__", line 3, in __main__.median
Failed example:
    median([2, 9, 9, 7, 9, 2, 4, 5, 8])
Expected:
    8
Got:
    7
**********************************************************************
1 items had failures:
   1 of   1 in __main__.median
***Test Failed*** 1 failures.
*** DocTestRunner.merge: '__main__.median' in both testers; summing outcomes.
*** DocTestRunner.merge: '__main__' in both testers; summing outcomes.
TestResults(failed=1, attempted=1)

doctest模块在程序说明中寻找看起来像python交互程序的字符串,然后把这些字符串作为python代码运行,验证他们运行后是否得到想要的结果。这里有3种需求会用到doctest。
1. 验证模块(例如,方法)中的文档或说明书是否得及时更新。
2. 执行回归测试(regression test)。
3. 写培训文档,或说明文档,有点程序可读性测试的味道。
总之,doctest按文档中的指令执行,其实就是按照预先给定的参数执行该模块,然后对比实际输出结果是否与说明中的结果一致。其结果就反映了以上3个方面,1,有可能程序正确,文档说明没有及时更新;2,修改后的程序有bug;3,由于程序的执行结果与文档说明中的不一致,很可能导致读者困惑,程序可读性受影响。
下面举一个小例子,麻雀虽小五脏俱全。
def factorial (n):
    '''Return the factorial of n, an exact integer >= 0.
    If the result is small enough to fit in an int, return an int.
    Else return a long.
    >>> [factorial(n) for n in range(6)] #看看python的语法就是这么简洁
    [1, 1, 2, 6, 24, 120]
    >>> [factorial(long(n)) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000L
    >>> factorial(30L)
    265252859812191058636308480000000L
    >>> factorial(-1)
    Traceback (most recent call last):
    ...
    ValueError: n must be >= 0
    
    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
    ...
    ValueError: n must be exact integer
    >>> factorial(1e100)
    Traceback (most recent call last):
    ...
    OverflowError: n too large
    ''' #三引号引起来的字都是说明
    
    import math
    if not n>=0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n: # cache a value like le300
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result
    
if __name__ == "__main__":
    import doctest
    doctest.testmod()
以上代码需要保存到C:\Python26\Lib\site-packages\win32\test\example.py。然后再命令行里直接运行它:
>python example.py
>
没有输出,那就对了,意味着所有的例子多是正确的。如果命令行后加参数-v,doctest将会把详细的记录打印出来,做一个总结。
/home/finance/.conda/envs/py311/lib/python3.11/site-packages/distributed/node.py:187: UserWarning: Port 8787 is already in use. Perhaps you already have a cluster running? Hosting the HTTP server on port 46573 instead warnings.warn( 2025-09-08 23:14:11,403 - distributed.protocol.pickle - ERROR - Failed to serialize <function train_model at 0x7f454c4619e0>. Traceback (most recent call last): File "/home/finance/.conda/envs/py311/lib/python3.11/site-packages/distributed/protocol/pickle.py", line 73, in dumps result = cloudpickle.dumps(x, **dump_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/finance/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py", line 1537, in dumps cp.dump(obj) File "/home/finance/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py", line 1303, in dump return super().dump(obj) ^^^^^^^^^^^^^^^^^ TypeError: cannot pickle '_asyncio.Task' object During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/finance/.conda/envs/py311/lib/python3.11/site-packages/distributed/protocol/pickle.py", line 77, in dumps result = cloudpickle.dumps(x, **dump_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/finance/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py", line 1537, in dumps cp.dump(obj) File "/home/finance/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py", line 1303, in dump return super().dump(obj) ^^^^^^^^^^^^^^^^^ TypeError: cannot pickle '_asyncio.Task' object Dashboard: http://127.0.0.1:46573/status --------------------------------------------------------------------------- TypeError Traceback (most recent call last) File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/protocol/pickle.py:73, in dumps(x, buffer_callback, protocol) 72 buffers.clear() ---> 73 result = cloudpickle.dumps(x, **dump_kwargs) 74 except Exception: File ~/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py:1537, in dumps(obj, protocol, buffer_callback) 1536 cp = Pickler(file, protocol=protocol, buffer_callback=buffer_callback) -> 1537 cp.dump(obj) 1538 return file.getvalue() File ~/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py:1303, in Pickler.dump(self, obj) 1302 try: -> 1303 return super().dump(obj) 1304 except RuntimeError as e: TypeError: cannot pickle '_asyncio.Task' object During handling of the above exception, another exception occurred: TypeError Traceback (most recent call last) Cell In[17], line 49 45 return future, start 48 # 启动异步训练 ---> 49 future, start_time = client.run(train_model) 51 # 监控任务状态 52 while not future.done(): File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/client.py:3188, in Client.run(self, function, workers, wait, nanny, on_error, *args, **kwargs) 3105 def run( 3106 self, 3107 function, (...) 3113 **kwargs, 3114 ): 3115 """ 3116 Run a function on all workers outside of task scheduling system 3117 (...) 3186 >>> c.run(print_state, wait=False) # doctest: +SKIP 3187 """ -> 3188 return self.sync( 3189 self._run, 3190 function, 3191 *args, 3192 workers=workers, 3193 wait=wait, 3194 nanny=nanny, 3195 on_error=on_error, 3196 **kwargs, 3197 ) File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/utils.py:376, in SyncMethodMixin.sync(self, func, asynchronous, callback_timeout, *args, **kwargs) 374 return future 375 else: --> 376 return sync( 377 self.loop, func, *args, callback_timeout=callback_timeout, **kwargs 378 ) File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/utils.py:452, in sync(loop, func, callback_timeout, *args, **kwargs) 449 wait(10) 451 if error is not None: --> 452 raise error 453 else: 454 return result File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/utils.py:426, in sync.<locals>.f() 424 awaitable = wait_for(awaitable, timeout) 425 future = asyncio.ensure_future(awaitable) --> 426 result = yield future 427 except Exception as exception: 428 error = exception File ~/.conda/envs/py311/lib/python3.11/site-packages/tornado/gen.py:769, in Runner.run(self) 767 try: 768 try: --> 769 value = future.result() 770 except Exception as e: 771 # Save the exception for later. It's important that 772 # gen.throw() not be called inside this try/except block 773 # because that makes sys.exc_info behave unexpectedly. 774 exc: Optional[Exception] = e File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/client.py:3068, in Client._run(self, function, nanny, workers, wait, on_error, *args, **kwargs) 3055 async def _run( 3056 self, 3057 function, (...) 3063 **kwargs, 3064 ): 3065 responses = await self.scheduler.broadcast( 3066 msg=dict( 3067 op="run", -> 3068 function=dumps(function), 3069 args=dumps(args), 3070 wait=wait, 3071 kwargs=dumps(kwargs), 3072 ), 3073 workers=workers, 3074 nanny=nanny, 3075 on_error="return_pickle", 3076 ) 3077 results = {} 3078 for key, resp in responses.items(): File ~/.conda/envs/py311/lib/python3.11/site-packages/distributed/protocol/pickle.py:77, in dumps(x, buffer_callback, protocol) 75 try: 76 buffers.clear() ---> 77 result = cloudpickle.dumps(x, **dump_kwargs) 78 except Exception: 79 logger.exception("Failed to serialize %s.", x) File ~/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py:1537, in dumps(obj, protocol, buffer_callback) 1535 with io.BytesIO() as file: 1536 cp = Pickler(file, protocol=protocol, buffer_callback=buffer_callback) -> 1537 cp.dump(obj) 1538 return file.getvalue() File ~/.conda/envs/py311/lib/python3.11/site-packages/cloudpickle/cloudpickle.py:1303, in Pickler.dump(self, obj) 1301 def dump(self, obj): 1302 try: -> 1303 return super().dump(obj) 1304 except RuntimeError as e: 1305 if len(e.args) > 0 and "recursion" in e.args[0]: TypeError: cannot pickle '_asyncio.Task' object
最新发布
09-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值