当前位置: 首页 > news >正文

Python 装饰器与函数调用机制(复习笔记 · 2026-07-07)

一、最基础:def 是定义,() 是调用

  • def say_hello(): print("Hello!")——只定义,不执行。函数体被"存起来",不打印任何东西。
  • say_hello()——有括号 = 调用 = 真正执行,才会打印 "Hello!"。
  • 如果删掉调用那行,程序什么都不输出(函数只定义、从没被喊去跑)。

❗ 误区:以为@装饰器会自动让函数运行。不会,必须显式写名字()才执行。

二、无参装饰器:名字被重新贴到 wrapper 上

def my_decorator(func): def wrapper(): print("函数执行前") func() print("函数执行后") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello()

执行流程

  1. def my_decorator:定义装饰器函数(不跑)。
  2. def say_hello:定义原函数(不跑)。
  3. @my_decorator等价于say_hello = my_decorator(say_hello)
    • 调用 my_decorator,传入原函数;
    • 内部定义 wrapper(不跑),return wrapper把 wrapper 交出去;
    • say_hello这个名字现在指向 wrapper(不再是原函数)。
  4. say_hello()实际执行wrapper()
函数执行前 Hello! 函数执行后

关键结论

  • @装饰器本质 =函数名 = 装饰器(函数名),把名字重新绑定到新函数。
  • 装饰器执行时(@那行)只定义和返回,不打印;打印发生在你后续调用时。
  • 没有调用那行 → 什么都不输出。

三、Python 的"指向"不是 C 指针(重要纠偏)

❗ 当时类比错了的地方,已全部纠正:

原错误类比

正确概念

方法是内存块,指针从上往下扫到哪执行到哪

def语句本身执行了(创建函数对象),但函数体不执行,只是存起来等调用

指向像 C 指针,知道内存哪块就跳去执行

Python 名字是引用/reference(标签贴对象),不是 C 指针,不能指针运算

占多少内存要关心

函数对象很小(几百字节),Python 有自动 GC,学习阶段不用管内存

Python 有指针

没有指针;有调用栈、有 list(动态数组)、有 numpy.ndarray(AI 必用)

Java 学习者对照表(学过 Java,基本能直接迁移)

Java 认知

Python 对应

方法定义不运行,要 obj.method() 才调

✅ 一样,def 不跑,func() 才跑

对象靠引用、有 GC、有调用栈/堆

✅ Python 一样,且一切皆对象(连函数都是)

primitive 在栈、对象在堆

Python 更统一:全是对象、全靠引用

无裸指针、不能指针运算

✅ Python 也没有

要 new 才创建对象

Python不用 new,赋值即创建

要手动 free/delete

Python 自动 GC,不用管

唯一要"忘掉"的:C 的手动内存管理 + 指针算术。Python 比 Java 还省心。

四、(*args, **kwargs):装饰器的"万能接口"

def wrapper(*args, **kwargs): result = original_function(*args, **kwargs) return result
  • 调用target_function()(空括号)→args=()空元组、kwargs={}空字典,啥都没接
  • target_function(1, 2, name="小澪")args=(1,2)kwargs={'name':'小澪'}

写法

接住

存为

*args

位置参数(按顺序的值)

元组 tuple

**kwargs

关键字参数(名字=值)

字典 dict

  • 定义处的*/**=收集(打包收到的参数)。
  • 调用处的original_function(*args, **kwargs)*/**=解包(摊开传回去)。
  • 作用:让装饰器通用,不管被装饰函数要不要参数都能透传。无参函数传空进去正好。

❗ 误区:以为(*args, **kwargs)是"必须填两个"。不是,是"能接住任意参数"的兜底,不传就都是空的。

五、带参装饰器(装饰器工厂)= 多一层

def repeat(num_times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(num_times): func(*args, **kwargs) return wrapper return decorator @repeat(3) def say_hello(): print("Hello!") say_hello()

三层接参(最关键,别混)

函数

接住

来自

1

repeat(num_times)

配置参数 3

repeat(3)

2

decorator(func)

被装饰函数 say_hello

@语法

3

wrapper(*args, **kwargs)

调用时参数

say_hello()

❗ 当时误解:@repeat(3)把 say_hello 传给了 repeat。错!

  • repeat(3)先算 → 传num_times=3→ 返回decorator(内部记住 num_times=3)。
  • 然后@decorator才把say_hello传给decoratorfunc
  • 不是同一个函数接的两个东西,是先吃配置、再吐出一个定制装饰器去接函数。

对比无参装饰器

无参@df

带参@repeat(3)

df 直接接原函数

repeat 先接 3 → 吐 decorator;decorator 再接原函数

两层(df / wrapper)

三层(repeat / decorator / wrapper)

多出的repeat层唯一作用:接收配置参数,返回真正能装饰函数的 decorator→ 所以叫"装饰器工厂"。

六、for _ in range(n):循环 n 次

  • range(3)产生0, 1, 2(从 0 到 n-1,共 n 个)。
  • for _ in range(n):= "循环 n 次",每轮执行缩进块。
  • _是占位变量名,表示"这个数我不用",纯占位(写for i in ...也一样,只是 i 没被用)。
  • 带参装饰器打印三次,就是for _ in range(num_times)num_times=3决定的;改成 5 就打印 5 次。
  • range()不是列表,是惰性序列,省内存,学习阶段只需知道"range(n)= 0 到 n-1 共 n 个数"。

七、今日核心心法(背下来)

  1. def造函数不跑,名字()才跑。
  1. @装饰器=函数名 = 装饰器(函数名),名字被重新指向新函数。
  1. 没写调用 → 不输出;要输出必须显式名字()
  1. 名字是引用不是指针,内存 Python 自动管。
  1. (*args, **kwargs)是装饰器万能接口,定义处收集、调用处解包。
  1. 带参装饰器多一层"工厂":先收配置、再产装饰器、最后接函数。
  1. range(n)+for= 循环 n 次;_是占位变量。
http://www.jsqmd.com/news/1145293/

相关文章:

  • 2026光选机品牌实测评测:四家头部6维度横评(分得利/陶朗/弓叶/美亚)
  • 多工位转台组合机床选型参考:国产秋竹机床与进口设备差异化解析
  • 2026saas建站平台有哪些
  • Frida 15.2.2 Hook HashMap.put 实战:抖音 23.9 版本六神参数拦截与日志分析
  • 跨形态动作表征对齐:让机器人真正看懂并学会人类动作
  • vue与ts不得不说的秘密
  • 学生党如何零成本入门AI编程?2026年免费工具清单+学习路线
  • 自动售货机场地合同到期,续签时这几个条款一定要看清~YH
  • 【类型转换】
  • 有机废气治理企业怎么选?主流 VOC 治理工艺与靠谱服务商全解析
  • AI写代码越改越乱?多文件修改中的上下文、依赖冲突和代码冲突
  • 海思网络错误(烧录报tftp错误等)解决思路分享
  • 特赞 Clipo idea 发布:AI 正在进入社媒内容的“投前决策”环节
  • 秋招简历怎么写才能过初筛?资深HR揭秘5大核心技巧
  • Linux KVM 潜伏 16 年的漏洞终于被发现:一个虚拟机就能搞崩整台物理服务器
  • 通信拓扑如何决定多机器人协同性能上限
  • 一招搞定!经纬度转海拔,批量自动填充,坐标信息一键导出
  • Point-BERT 与 Point-MAE 对比:掩码建模策略对 3D 点云 Transformer 性能的 2 点核心差异
  • 终极Wwise音频容器解析指南:如何免费快速修改游戏音频文件
  • AI 是一个可以降本增效的完美存在
  • 3大创新突破:ChemBERTa如何重新定义化学AI研究范式
  • linux C++到指定路径下获取指定后缀文件名
  • Spring AI Agentic 模式(第1部分):Agent Skills——模块化、可复用的能力
  • web作业10
  • 房地产顾问如何突破单一业务模式转型为家族资产配置顾问?
  • 还在为 API 调用踩坑?这款中转站帮你省成本、提效率、保稳定
  • ETCD 集群写满导致集群退出
  • 多通道数据采集仪
  • 在家也能安全连内网数据库:MariaDB监控与公网访问实战
  • AI核心组件:从感知到行动,打造超级智能体!