答案页 · 12 道题

Python 装饰器练习答案

本页汇总 Python 装饰器 的 12 道练习。先做练习页,再回到这里核对准确答案和原因。

快速答案

本答案页包含 Python 装饰器 的 4 道选择题、4 道填空题和 4 道输出预测题,每题都给出准确答案和简短解释。

答案已完整展示,建议先尝试作答,再用本页核对。第一次练习最好从互动练习页开始。

01 · 选择题

装饰器接收什么,又返回什么?

  1. 一个函数和一个替代的可调用对象正确答案
  2. 一个字符串和数字
  3. 一个类和实例
  4. 一个模块和包

答案: 一个函数和一个替代的可调用对象

为什么: 装饰器接收函数,并返回一个通常会包装它的可调用对象。

02 · 选择题

代码的输出结果是什么?

def deco(f):
    def wrapper():
        return f() + "!"
    return wrapper

@deco
def hi():
    return "hi"
print(hi())
  1. hi
  2. None
  3. hi!正确答案
  4. !hi

答案: hi!

为什么: 包装函数在原结果后加了一个感叹号。

03 · 选择题

@deco 放在 def f 上方,等价于什么?

  1. 只调用 deco(f) 但不赋值
  2. f = f(deco)
  3. f = deco(f)正确答案
  4. deco = f(deco)

答案: f = deco(f)

为什么: 装饰器在定义时应用,返回值会替换名字 f。

04 · 选择题

为什么要使用 functools.wraps?

  1. 把函数转换成类
  2. 保留原函数的元数据正确答案
  3. 调用函数两次
  4. 让包装函数运行得更快

答案: 保留原函数的元数据

为什么: wraps 会把名字、文档字符串等元数据复制到包装函数上。

05 · 填空题

补全提供 wraps 的模块。

from ____ import wraps

答案: functools

为什么: wraps 位于 functools 模块中。

06 · 填空题

补全装饰器的返回值。

def deco(f):
    def wrapper():
        return f()
    return ____

答案: wrapper

为什么: 装饰器必须返回内部的包装函数。

07 · 填空题

补全收集位置参数的参数名。

def deco(f):
    def wrapper(*args, **kwargs):
        return f(*____, **kwargs)
    return wrapper

答案: args

为什么: 包装函数通过 args 转发所有位置参数。

08 · 填空题

补全保留元数据的辅助函数。

from functools import ____

答案: wraps

为什么: wraps 会保留被装饰函数的身份信息。

09 · 输出预测

屏幕上会显示什么?

def deco(f):
    def wrapper():
        return f() * 2
    return wrapper

@deco
def word():
    return "ab"
print(word())

答案: abab

为什么: 包装函数把字符串重复两次,ab 变成 abab。

10 · 输出预测

这段代码会输出什么?

def deco(f):
    def wrapper():
        return f().upper()
    return wrapper

@deco
def word():
    return "hi"
print(word())

答案: HI

为什么: 包装函数把结果转成大写,hi 变成 HI。

11 · 输出预测

运行结果是什么?

def deco(f):
    def wrapper():
        return "[" + f() + "]"
    return wrapper

@deco
def word():
    return "ok"
print(word())

答案: [ok]

为什么: 包装函数在 ok 两边加上方括号。

12 · 输出预测

这段程序打印出什么?

from functools import wraps
def deco(f):
    @wraps(f)
    def wrapper():
        return f()
    return wrapper
@deco
def hello():
    return "hi"
print(hello.__name__)

答案: hello

为什么: wraps 复制了原函数名,所以输出 hello。

先试一遍题目

打开 Python 装饰器 练习页,用即时反馈回答同样的 12 道题。

练习本课