如何在将其作为参数传递时获取函数的属性

时间:2014-08-26 15:38:48

标签: python lambda

我发现如果你想传递一个带参数作为参数的函数,你应该使用lambda函数。

我想要实现的是,evaluate函数查找已在其参数中传递的函数的属性。我怀疑这是可能的,但我并不完全熟悉lambda的工作原理。

def do_something(foo):
"""this functions raises an Exception"""
    print foo
    raise Exception


def evaluate(funct, testname):
"""In this function I want to evaluate by example whether it throws exceptions"""
    try:
        if hasattr(funct, '__call__'):
            funct()
    except Exception:
        print "Error in "+ testname+ " " + funct.__name___ + " " + funct.__doc__

通过示例,我希望有这样的印刷品

>>>evaluate(lambda: do_something("foo"), "The Test Suite")
foo
Error in The Test Suite do_something this functions raises an Exception

3 个答案:

答案 0 :(得分:4)

原始代码名为evaluate,带有函数但没有args。当评估者调用该函数时,它没有传递任何东西。考虑传递函数(对于文档和名称),预先调用的函数调用。使用partial在新对象中编码函数及其参数。这意味着求值程序可以使用args调用该函数,并捕获引发的异常。

更简单的版本(evaluate2)首先放置测试名称,然后是函数,然后是函数的args。通过这种方式,调用者不需要显式调用partial()

为了获得额外的惊人效果,您可以打印出调用者传入的内容,以及来自追溯的大量其他有价值的信息。请参阅:inspect

from functools import partial

def do_something(foo, bar):
    """this function raises an Exception"""
    print foo,bar
    raise Exception('uhoh')

def evaluate(fcall, testname):
    "print message if func call throws exception"
    try:
        fcall()
    except Exception:
        funct = fcall.func
        print ("Error in "+ testname+ " " 
               + funct.__name__ 
               + " " + funct.__doc__
               )

def evaluate2(testname, funct, *args, **kwargs):
    "print message if func call throws exception"
    try:
        funct(*args, **kwargs)
    except Exception:
        print ("Error in "+ testname+ " " 
               + funct.__name__ 
               + " " + funct.__doc__
               )

evaluate(partial(do_something, foo='beer'), 'mytest')
evaluate2('mytest2', do_something, 'tasty', foo='beer')

输出

Error in mytest do_something this function raises an Exception
Error in mytest2 do_something this function raises an Exception

答案 1 :(得分:2)

我认为你根本不需要使用lambda函数。如果我打电话

评估(do_something," The Test Suite")

...我得到你期望的输出。据我所知,lambda函数只是一种方便 - 你可以随时使用"常规"相反的功能(恕我直言,这通常更清楚)。

答案 2 :(得分:1)

使用shavenwarthog的答案,我认为你需要在对evaluate()的调用中提供函数的参数。但是,使用functools可能没有必要。以下代码是否符合您的要求?

def do_something(foo):
    """this function raises an Exception"""
    print foo
    raise Exception

def do_something_else(foo1, foo2, foo3):
    """this function also raises an Exception"""
    print foo1, foo2, foo3
    raise Exception


def evaluate(funct, args, testname):
    """In this function I want to evaluate by example whether it throws exceptions"""
    try:
        if hasattr(funct, '__call__'):
            funct(*args)
    except Exception:
        print "Error in "+ testname+ " " + funct.__name__ + " " + funct.__doc__



if __name__ == '__main__':
    evaluate( do_something, ("foo",), "The Test Suite")
    evaluate( do_something_else, ("a string", 1, [2,3,4]), "The Test Suite")