在 python 装饰器中传递给另一个函数时的变量范围

Scope of variable when passed to another function in python decorators

所以我正在阅读这篇 wonderful piece,它试图解释 python 中的装饰器。

我的问题特定于此代码段。

def surround_with(surrounding):
    """Return a function that takes a single argument and."""
    def surround_with_value(word):
        return '{}{}{}'.format(surrounding, word, surrounding)
    return surround_with_value

def transform_words(content, targets, transform):
    """Return a string based on *content* but with each occurrence 
    of words in *targets* replaced with
    the result of applying *transform* to it."""
    result = ''
    for word in content.split():
        if word in targets:
            result += ' {}'.format(transform(word))
        else:
            result += ' {}'.format(word)
    return result

markdown_string = 'My name is Jeff Knupp and I like Python but I do not own a Python'
markdown_string_italicized = transform_words(markdown_string, ['Python', 'Jeff'],
        surround_with('*'))
print(markdown_string_italicized)

我不明白的是,函数 surround_with() 是如何在其范围内获取变量 word(当 transform(word)transform_words() 中传递时)?我的意思是我们只声明了一个保持变量(作为函数参数)来表示周围的值应该是什么,没有别的。那么 word 是如何可用的呢?

我在这里错过了什么?

我想我明白了,

当我们调用 surround_with('*') 时,它 returns 函数 surround_with_value() 然后返回值 '{}{}{}'.format('*', word, '*').

现在,同一个函数接受一个参数(此处为 word),然后在 transform_words() 内部传递并重命名为 transform()

在其中我们最终传递了 word 的值。

surround_with()函数returns另一个带有闭包的函数对象:

def surround_with(surrounding):
    """Return a function that takes a single argument and."""
    def surround_with_value(word):
        return '{}{}{}'.format(surrounding, word, surrounding)
    return surround_with_value

所以返回surround_with_value;正是这个函数将 surrounding 的值添加到传入的任何内容中:

>>> def surround_with(surrounding):
...     """Return a function that takes a single argument and."""
...     def surround_with_value(word):
...         return '{}{}{}'.format(surrounding, word, surrounding)
...     return surround_with_value
...
>>> function = surround_with(' foo ')
>>> function
<function surround_with_value at 0x108ac16e0>
>>> function('bar')
' foo bar foo '

返回了 surround_with_value() 函数,并且对它的引用存储在名称 function 中。该函数对象引用 surrounding 作为 闭包 :

>>> function.__closure__
(<cell at 0x108a8a590: str object at 0x1074c4060>,)
>>> function.__closure__[0].cell_contents
' foo '

并且每次调用它时,都会取消引用闭包并使用其中的内容。

因此 surround_with() 生成一个函数对象,并且该函数(作为 surround_with('*') 的结果)作为第三个参数传递给 transform_words()

transform_words(markdown_string, ['Python', 'Jeff'],
        surround_with('*'))

所以赋值给变量transform:

def transform_words(content, targets, transform):

因此,每次调用 transform 时,您实际上是在调用嵌套的 surround_with_value() 函数,其中 '*' 作为 surrounding 闭包,并且 word正在传入:

result += ' {}'.format(transform(word))

闭包可能会让人非常困惑,这个例子可能不是展示 为什么 surround_with_value() 记得 环绕的最好例子with(surrounding) 事件,如果它不在它的范围内。

我强烈建议您阅读这篇优秀的博客,其中展示了您需要了解的所有概念以了解装饰器。 Step1:作用域-->Step2:闭包-->Step3:装饰器

花点时间从头读一遍。 http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/