【问题标题】:How to use function decorators to check type of function?如何使用函数装饰器检查函数类型?
【发布时间】:2019-12-05 00:07:27
【问题描述】:

如何使用函数装饰器来检查另一个函数的参数?我正试图围绕函数装饰器进行思考,但这非常令人困惑。

理想情况下,我希望它像这样工作,你在下面传入一个 int 和一个函数,该函数可以正常工作,否则你会得到一个类型错误。

@check(int)
def printer(arg):
    print(arg)
>>> printer(5)
5

这是我尝试过的,但它不起作用。

def check(typ):

    def validate(args):
        if type(args) == typ:
           return validate(args)
        else:
           raise TypeError

    return validate

任何建议或指导都将不胜感激,我一直在努力将我的头脑围绕在装饰器上。

【问题讨论】:

  • 这不是一个特定的错误,代码不正确,因为我不明白如何构造它,因为我无法理解如何从装饰器传入参数并将其与函数参数进行比较。
  • 您的主要主题是获取函数类型,并在代码中检查参数类型。请清楚地问你想知道什么。作为回答,我用外行语言写了关于装饰器的文章。

标签: python python-3.x python-decorators


【解决方案1】:

check(int) 还是要返回一个函数。

def check(typ):
    def checker(f):
        def checked_func(arg):
            if isinstance(arg, typ):
                return f(arg)
            else:
                raise TypeError
        return checked_func
    return checker

现在,_check 返回的实际装饰器,_ 采用原始函数并将其包装在 另一个 函数中,该函数检查参数的类型,然后返回应用于参数的原始函数的结果,或引发 TypeError。

如果我们把它分成更多的部分,可能会更容易理解。

int_checker = check(int)

@int_checker
def printer(arg):
    print(arg)

【讨论】:

  • 谢谢!这就是你所说的 f(arg) 我无法概念化的地方,但看到它写出来很有意义。我在包装这些东西的顺序上遇到了麻烦。为什么返回检查器不接受任何参数?
  • 它帮助我从底层构建装饰器。首先定义你希望printer 被替换的函数,然后用一个以printer 作为参数并在替换中使用它的函数包装它。然后将 that 包装在一个抽象出您正在检查的类型的函数中。
  • 另外请记住,装饰只是函数应用和变量赋值组合的语法糖:@func(x) def foo():...def foo():...; foo = func(foo) 相同。
  • 好的,有道理。再次感谢。
【解决方案2】:

在 python 中,一切都是对象,甚至函数也是。 让我用不同的方式写函数只是为了表达

def fun(arg):

可以表示为

fun(a variable) = function(arg) # just like we write in JS

所以我们也可以为变量分配不同的值。同样,我们可以为给定的函数名称分配不同的函数。

简而言之,装饰器的含义是为编写它的函数名称分配不同的函数

@deco
def func(arg):

相同
 func = deco(func)

为此,装饰器的返回类型应该是指向另一个函数的指针。

所以装饰器语法就像 -

def deco_func(func): # the parameter is a function
    def wrap_func(args):  #the args are the argument of original function
        #what ever you want to do
        return func(args) #call for original function
retunr wrap_func   # returning of the pointer of the wrap function.

【讨论】:

    猜你喜欢
    • 2013-02-24
    • 1970-01-01
    • 2019-07-23
    • 2018-01-12
    • 2021-04-14
    • 2015-05-27
    • 2019-07-29
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多