首页 > 解决方案 > 有没有办法将函数作为参数,但在给出返回值之前以某种方式修改函数调用?

问题描述

供参考,我是初学者。

我正在尝试制作一个“测试”其他功能的功能,没有什么复杂或任何东西。展示比解释更容易:

def test(function, actual, expected):
    print("Testing ", function)
    print("Expected result:", expected,  "Actual result:", actual)

就目前而言,函数的名称和参数分别作为字符串输入:

test("function(5)", function(5), expected)

我正在寻找一种将实际函数调用(第二个参数/参数)作为字符串(在本例中为“function(5)”)获取的方法,因为现在它被视为返回值测试'函数被调用。

标签: python

解决方案


您需要将参数作为参数传递给函数。这就是python的单元测试框架是如何做到的。您的函数将如下所示:

def test(function_name, expected, function, *args, **kwargs):
    print("Testing ", function_name)
    print("Expected result:", expected, "Actual result:", function(*args, **kwargs))

test("function(5)", expected, function, 5)

传递函数的每个参数或关键字参数都将被解包到函数中。

expected我将参数移到函数之前的原因是,对于假定为test函数的参数和假定传递给function.

另一个让您省略名称的解决方案:

def test(expected, function, *args, **kwargs):
    kwargs_repr = [f'{a}={b}' for a, b in kwargs.items()]
    arguments   = ', '.join(str(arg) for arg in (*args, *kwargs_repr)) 
    print(f"Testing if {function.__name__}({arguments}) equals {expected}")
    print("Expected result:", expected, "Actual result:", function(*args, **kwargs))

test(expected, function, 5)

为了更完整,您还应该捕获函数可能引发的任何错误。

def test(expected, function, *args, **kwargs):
    kwargs_repr = [f'{a}={b}' for a, b in kwargs.items()]
    arguments   = ', '.join(str(arg) for arg in (*args, *kwargs_repr)) 
    print(f"Testing if {function.__name__}({arguments}) equals {expected}")
    try:
        print("Expected result:", expected, "Actual result:", function(*args, **kwargs))
    except Exception as e:
        print(f"Function raised exception: {e}")

test(None, print, 5, 3, end=' ', abc='hello')

测试 print(1, 2, sep=123, end=hello, abc=123)
函数引发异常:'abc' 是 print() 的无效关键字参数


推荐阅读