拦截函数调用的python方法?

2024-05-17 05:44:15 发布

您现在位置:Python中文网/ 问答频道 /正文

对于测试查询环境的东西(例如,os.getenvsys.version等),使查询撒谎通常比实际伪造环境更方便。下面是一个上下文管理器,它一次只对一个os.getenv调用执行此操作:

from __future__ import with_statement
from contextlib import contextmanager
import os

@contextmanager
def fake_env(**fakes):
    '''fakes is a dict mapping variables to their values. In the
    fake_env context, os.getenv calls try to return out of the fakes
    dict whenever possible before querying the actual environment.
    '''

    global os
    original = os.getenv

    def dummy(var):
        try: return fakes[var]
        except KeyError: return original(var)

    os.getenv = dummy
    yield
    os.getenv = original

if __name__ == '__main__':

    print os.getenv('HOME') 
    with fake_env(HOME='here'):
        print os.getenv('HOME') 
    print os.getenv('HOME') 

但这只适用于os.getenv,如果允许使用多个参数的函数,语法会变得有点笨拙。我想在astcode/exec/eval之间,我可以扩展它,将要重写的函数作为一个参数,但不能很干净。同时,我也会去参加格林斯潘的第十场比赛。有更好的方法吗?在


Tags: thefromimportenvhomereturn环境os
2条回答

您可以很容易地将os.getenv本身作为第一个参数传递,然后在上下文管理器中分析它,比astcode等简单得多:

>>> os.getenv.__name__
'getenv'
>>> os.getenv.__module__
'os'

之后,出于合理的一般用途,您可以返回result对象,或者从参数(可能是其中的元组)到结果的映射。faker上下文管理器还可以选择接受一个可用于伪造的调用。在

例如,尽可能简单:

^{pr2}$

你的具体例子可以是:

with faker(os.getenv, dict(HOME='here').__getitem__):
   ...

当然,如果您希望传播某些异常而不是将punting传递到原始函数,或者在提供fakefun callable是笨重的一些常见情况下简化一些,则可能需要稍微复杂一点。但是,没有理由这样一个普通的造假者需要比你的特定造假者复杂得多。在

为什么不编写自己的(假的)sysos,以及c.模块呢?在

import fakeSys as sys

相关问题 更多 >