fc5igm 发表于 2021-6-14 00:45:04

关于修饰符的一些问题

def a_new_decorator(a_func):

    def wrapTheFunction():
      print("I am doing some boring work before executing a_func()")

      a_func()

      print("I am doing some boring work after executing a_func()")

    return wrapTheFunction

@a_new_decorator
def a_function_requiring_decoration():
    """Hey you! Decorate me!"""
    print("I am the function which needs some decoration to "
          "remove my foul smell")
以上代码,我不太明白为什么会:
print(a_function_requiring_decoration.__name__)
# Output: wrapTheFunction
为什么输出的是wrapTheFunction而不是a_new_decorator啊?

在没做修饰符之前
>>> print(a_function_requiring_decoration.__name__)
a_function_requiring_decoration
>>> print(a_new_decorator.__name__)
a_new_decorator
修饰符不是类似于把一个函数当作参数填入另一个函数么?
那现在a_function_requring_decoration被当作了a_new_decorator的参数,为什么属性__name__返回的却不是a_new_decorator,反而是该函数下的子函数名warpTheFunction啊?

Twilight6 发表于 2021-6-14 01:30:04


这个与使用修饰符后的代码执行的顺序有关,这里你 12~16 行代码定义相当于定义:

temp = a_new_decorator(a_function_requiring_decoration)

实际上此时你 a_function_requiring_decoration() 相当于调用 temp()

即 temp =a_function_requiring_decoration 又因为 temp 接收 a_new_decorator 函数返回值,即返回函数体 wrapTheFunction

所以此时你用修饰符修饰完之后,a_new_decorator.__name__ 实际上就为 wrapTheFunction.__name__

这里相同变量名我帮你标注了颜色,看上去舒服些(PS:这里 temp 只是拿来做临时接受返回值的,方便描述,实际上并没有 temp 赋值这个过程)

fc5igm 发表于 2021-6-14 02:16:57

Twilight6 发表于 2021-6-14 01:30
这个与使用修饰符后的代码执行的顺序有关,这里你 12~16 行代码定义相当于定义:

temp = a_new_decor ...

懂了懂了。也就是说,我也不知道我这么描述对不对...
但是就是说,最开始a_new_decorator相当于一个未激活的函数,要想激活它需要加一对括号。
当他被加了一对括号之后,a_new_decorator就会返回一个叫做warpTheFunction的未激活函数
那此时再用__name__属性调用的话,就会显示出来warpTheFunction的名字了
而你举例用的temp也好,或者经过修饰符修饰的变量a_function_requiring_decoration也罢,其实都是等于已经被激活过一次的a_new_decorator,也即等于未激活的warpTheFunction

我不知道用‘激活’来形容函数后加括号的行为对不对。。如果有专业的称呼还请斧正。
页: [1]
查看完整版本: 关于修饰符的一些问题