python装饰器,嵌套函数[重复]

Posted

技术标签:

【中文标题】python装饰器,嵌套函数[重复]【英文标题】:python decorators, nested function [duplicate] 【发布时间】:2015-06-11 01:02:37 【问题描述】:

我试图弄清楚为什么在使用装饰器时我还需要一个嵌套函数。这是一个例子:

 def func(f):
    def deco(*args, **kwargs):
        return f(*args, **kwargs)
    return deco

@func
def sum(a, b):
    return a+b

print sum(5, 10)

代码有效,一切都很好。但是为什么我需要创建嵌套的“deco”函数呢? 让我们尝试不使用它:

def func(f):
    return f(*args, **kwargs)

@func
def sum(a, b):
    return a+b

print sum(5, 10)

代码失败。

所以有三个问题:

    为什么第二个样本不起作用? 如果我们使用嵌套函数,为什么 args、kwargs 会“神奇地”出现? 我该怎么做才能使第二个样本工作?当然,除了嵌套另一个函数。

【问题讨论】:

装饰器应该返回一个函数而不是函数的结果。在您的第一个示例中,它返回一个函数......在第二个示例中,它返回您的函数 f 返回的任何内容。 第二个和第三个问题呢? *args**kwargs 不会“神奇地”出现,只有在调用装饰函数后才会定义参数 (***.com/questions/36901/…) 简而言之:因为装饰器的约定是它们是函数工厂:它们接受一个函数并返回一个新函数。在您的第二个示例中,您的func(f) 返回函数调用的结果。但是装饰器需要返回一个函数(还没有被调用)。 注意:@func 只是 sum = func(sum)argskwargs 的一些语法糖,只有当您调用 sum 的这个新定义时才有意义。 【参考方案1】:

    为什么第二个样本不起作用?

    因为您在返回时调用函数,所以您没有返回函数。

    如果我们使用嵌套函数,为什么 args,kwargs 会“神奇地”出现?

    它们不会神奇地出现,我们将它们声明为:

    def deco(*args, **kwargs):
    

    这些是通用的,将匹配任何函数签名(参数列表)。你不必叫他们argskwargs,这只是一个约定,你可以叫他们sharontracy

    我该怎么做才能使第二个样本工作?当然,除了嵌套另一个函数。

    嗯,你没有说你期望第二个样本做什么。但我想把它变成一个装饰器:

    def func(f):
        return f
    

    但这并没有多大作用!

顺便说一句,覆盖现有的 Python 内置函数 (sum) 通常是个坏主意——你必须有一个很好的理由。

【讨论】:

以上是关于python装饰器,嵌套函数[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python——装饰器

5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器

Python进阶精华-编写装饰器为被包装的函数添加参数

Python基础高阶函数+函数嵌套+闭包 ==装饰器

Python学习————python基础复习

Python3装饰器