小甲鱼 发表于 2026-2-20 02:25:15

本主题需向作者支付 5 鱼币 才能浏览 购买主题

不二如是 发表于 2026-2-20 12:06:32

{:10_256:}{:10_256:}第一

lf_jbw 发表于 2026-2-25 14:47:25

@FishC 表达式 label("VIP") 的结果最接近下面哪一项?

def label(tag):
    def deco(func):
      def wrapper():
            print(f"[{tag}]", end=" ")
            return func()
      return wrapper
    return deco

A. 一个字符串 "VIP"
B. 一个已经执行过的函数返回值
C. 一个装饰器函数(接收 func)
D. 一个模块对象

FishC 发表于 2026-2-25 14:47:51

lf_jbw 发表于 2026-02-25 14:47
@FishC 表达式 label("VIP") 的结果最接近下面哪一项 ...

表达式 label("VIP") 的结果是返回内部函数 deco,这是一个装饰器函数,它接收一个函数参数 func 并返回包装函数 wrapper。因此,最接近的选项是:

C. 一个装饰器函数(接收 func)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

lf_jbw 发表于 2026-2-25 14:48:59

@FishC 第二次调用 ping() 时,第一行会打印什么?

def count_calls(func):
    cnt = 0
    def wrapper():
      nonlocal cnt
      cnt += 1
      print(f"第{cnt}次")
      return func()
    return wrapper

@count_calls
def ping():
    print("ping")

ping()
ping()

A. 第1次
B. 第2次
C. ping
D. 报错

FishC 发表于 2026-2-25 14:49:27

lf_jbw 发表于 2026-02-25 14:48
@FishC 第二次调用 ping() 时,第一行会打印什么?

...

第二次调用 ping() 时,第一行会打印 第2次,所以正确答案是 B。

解释:
- @count_calls 装饰器会为 ping 函数添加一个计数器 cnt,每次调用 ping() 时,实际执行的是装饰器内部的 wrapper 函数。
- wrapper 首先递增 cnt,然后打印当前计数,再调用原始 ping 函数。

具体执行过程:
1. 第一次调用 ping():
   
   cnt 从 0 变为 1
   打印 "第1次"
   调用原始 ping(),打印 "ping"
   
2. 第二次调用 ping():
   
   cnt 从 1 变为 2
   打印 "第2次"
   调用原始 ping(),打印 "ping"
   

因此,第二次调用时第一行打印的是 "第2次"。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

haly 发表于 2026-4-2 06:15:59

@FishC 下面代码运行结果是?

def silent(func):
    def wrapper():
      return func()
    return wrapper

@silent
def add(a, b):
    return a + b

print(add(1, 2))

A. 3
B. None
C. 抛出 TypeError
D. 打印 1 和 2

FishC 发表于 2026-4-2 06:16:13

haly 发表于 2026-04-02 06:15
@FishC 下面代码运行结果是?

def silent(func):
...

装饰器 `@silent` 将 `add` 函数替换为 `wrapper` 函数,但 `wrapper` 函数没有定义参数,而调用 `add(1, 2)` 时传递了两个参数,导致参数不匹配,因此会抛出 `TypeError`。

def silent(func):
    def wrapper():
      return func()
    return wrapper

@silent
def add(a, b):
    return a + b

print(add(1, 2))# 抛出 TypeError: wrapper() takes 0 positional arguments but 2 were given

正确答案是:C。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

我还要学99 发表于 7 天前

@FishC 想让两次输出都约为 0.1 秒(而不是第二次更大),应把 start = time.time() 移到哪里?

import time

def watch(func):
    start = time.time()
    def wrapper():
      func()
      end = time.time()
      print(f"{end - start:.3f}")
    return wrapper

@watch
def task():
    time.sleep(0.1)

task()
task()

A. 移动到 wrapper 内部,放在 func() 调用之前
B. 移动到 wrapper 内部,放在 func() 调用之后
C. 保持在 watch() 外层不变
D. 移动到 task() 外部的全局位置

FishC 发表于 7 天前

我还要学99 发表于 2026-04-04 11:18
@FishC 想让两次输出都约为 0.1 秒(而不是第二次更大 ...

要解决这个问题,需要让每次调用 task() 时都重新记录开始时间,而不是使用装饰器定义时固定的开始时间。因此,应将 start = time.time() 移动到 wrapper 函数内部,并在调用 func() 之前执行。这样每次调用都会计算本次执行的时间差,输出约为 0.1 秒。

正确选项是:A. 移动到 wrapper 内部,放在 func() 调用之前

修改后的代码示例:

import time

def watch(func):
    def wrapper():
      start = time.time()# 每次调用时重新记录开始时间
      func()
      end = time.time()
      print(f"{end - start:.3f}")
    return wrapper

@watch
def task():
    time.sleep(0.1)

task()# 输出约 0.100
task()# 输出约 0.100


这样修改后,两次调用都会输出大约 0.1 秒的时间。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 第046讲:函数(VI)