<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.linuxsa.org/index.php?action=history&amp;feed=atom&amp;title=Python%E9%97%AD%E5%8C%85%E5%92%8C%E8%A3%85%E9%A5%B0%E5%99%A8</id>
	<title>Python闭包和装饰器 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.linuxsa.org/index.php?action=history&amp;feed=atom&amp;title=Python%E9%97%AD%E5%8C%85%E5%92%8C%E8%A3%85%E9%A5%B0%E5%99%A8"/>
	<link rel="alternate" type="text/html" href="https://wiki.linuxsa.org/index.php?title=Python%E9%97%AD%E5%8C%85%E5%92%8C%E8%A3%85%E9%A5%B0%E5%99%A8&amp;action=history"/>
	<updated>2026-04-23T10:43:34Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://wiki.linuxsa.org/index.php?title=Python%E9%97%AD%E5%8C%85%E5%92%8C%E8%A3%85%E9%A5%B0%E5%99%A8&amp;diff=905&amp;oldid=prev</id>
		<title>Evan：​/* decorator2025 */</title>
		<link rel="alternate" type="text/html" href="https://wiki.linuxsa.org/index.php?title=Python%E9%97%AD%E5%8C%85%E5%92%8C%E8%A3%85%E9%A5%B0%E5%99%A8&amp;diff=905&amp;oldid=prev"/>
		<updated>2025-05-18T14:42:07Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;decorator2025&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;要先理解闭包，再理解装饰器&lt;br /&gt;
&lt;br /&gt;
==闭包==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 什么是闭包&lt;br /&gt;
&lt;br /&gt;
#定义一个函数&lt;br /&gt;
def test(number):&lt;br /&gt;
&lt;br /&gt;
    #在函数内部再定义一个函数，并且这个函数用到了外边函数的变量，那么将这个函数以及用到的一些变量称之为闭包&lt;br /&gt;
    def test_in(number_in):&lt;br /&gt;
        print(&amp;quot;in test_in 函数, number_in is %d&amp;quot;%number_in)&lt;br /&gt;
        return number+number_in&lt;br /&gt;
    #其实这里返回的就是闭包的结果&lt;br /&gt;
    return test_in&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#给test函数赋值，这个20就是给参数number&lt;br /&gt;
这时候 ret 指向是test_in 也就是里面的那个function&lt;br /&gt;
ret = test(20)&lt;br /&gt;
&lt;br /&gt;
#注意这里的100其实给参数number_in&lt;br /&gt;
print(ret(100))&lt;br /&gt;
&lt;br /&gt;
#注意这里的200其实给参数number_in&lt;br /&gt;
print(ret(200))&lt;br /&gt;
运行结果：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
in test_in 函数, number_in is 100&lt;br /&gt;
120&lt;br /&gt;
&lt;br /&gt;
in test_in 函数, number_in is 200&lt;br /&gt;
220&lt;br /&gt;
&lt;br /&gt;
cat 1.py &lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
--1--&lt;br /&gt;
--3--&lt;br /&gt;
*************************&lt;br /&gt;
--2--&lt;br /&gt;
200&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
def test(number):&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;--1--&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def test_in():&lt;br /&gt;
        print(&amp;quot;--2--&amp;quot;)&lt;br /&gt;
        print(number+100)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;--3--&amp;quot;)&lt;br /&gt;
    return test_in&lt;br /&gt;
ret = test(100)&lt;br /&gt;
print(&amp;quot;*&amp;quot;*25)&lt;br /&gt;
ret()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
def test(number):&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;--1--&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def test_in():&lt;br /&gt;
        print(&amp;quot;--2--&amp;quot;)&lt;br /&gt;
        print(number+100)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;--3--&amp;quot;)&lt;br /&gt;
    return test_in&lt;br /&gt;
&lt;br /&gt;
test(100)&lt;br /&gt;
#ret = test(100)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
--1--&lt;br /&gt;
--3--&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def test(number):&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;--1--&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def test_in(number2):&lt;br /&gt;
        print(&amp;quot;--2--&amp;quot;)&lt;br /&gt;
        print(number+number2)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;--3--&amp;quot;)&lt;br /&gt;
    return test_in&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ret = test(100)&lt;br /&gt;
print(&amp;quot;-&amp;quot;*30)&lt;br /&gt;
ret(1)&lt;br /&gt;
ret(100)&lt;br /&gt;
ret(200)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 python3  01-闭包/01-闭包1.py &lt;br /&gt;
--1--&lt;br /&gt;
--3--&lt;br /&gt;
------------------------------&lt;br /&gt;
--2--&lt;br /&gt;
101&lt;br /&gt;
--2--&lt;br /&gt;
200&lt;br /&gt;
--2--&lt;br /&gt;
300&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==装饰器==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
现在，假设我们要增强now()函数的功能，比如，在函数调用前后自动打印日志，但又不希望修改now()函数的定义，这种在代码运行期间动态增加功能的方式，称之为“装饰器”（Decorator）。&lt;br /&gt;
&lt;br /&gt;
本质上，decorator就是一个返回函数的高阶函数。所以，我们要定义一个能打印日志的decorator，可以定义如下：&lt;br /&gt;
&lt;br /&gt;
把@log放到now()函数的定义处，相当于执行了语句：&lt;br /&gt;
now = log(now)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
---正在验证权限----&lt;br /&gt;
---f1---&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
def w1(func):&lt;br /&gt;
    def inner():&lt;br /&gt;
        print(&amp;quot;---正在验证权限----&amp;quot;)&lt;br /&gt;
        func()&lt;br /&gt;
    return inner&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
    print(&amp;quot;---f1---&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def f2():&lt;br /&gt;
    print(&amp;quot;---f2---&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
#innerFunc = w1(f1)&lt;br /&gt;
#innerFunc()&lt;br /&gt;
&lt;br /&gt;
#这是的f1 其实是inner了  只有func才是原来的f1&lt;br /&gt;
f1 = w1(f1)  &lt;br /&gt;
f1()&lt;br /&gt;
&lt;br /&gt;
运行流程如下  一开始是 f1 = w1(f1)   先算右边的 w1(f1)  这时候 func指向def f1 ，而左边的f1 为def inner  所以 运行最后一行 f1()时  就是先运行 inner fun 打印 ---正在验证权限----，第二步 func() 也就是原来的f1 fun 所以打印---f1---&lt;br /&gt;
&lt;br /&gt;
不明请看下面的wrapp原理图片&lt;br /&gt;
&amp;lt;2019-03-28 四&amp;gt;&lt;br /&gt;
&lt;br /&gt;
****************************分隔线**********************************************************&lt;br /&gt;
&lt;br /&gt;
#定义函数：完成包裹数据&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
----1---&lt;br /&gt;
----2---&lt;br /&gt;
----3---&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;hello world-3&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
def makeBold(fn):&lt;br /&gt;
    def wrapped():&lt;br /&gt;
        print(&amp;quot;----1---&amp;quot;)&lt;br /&gt;
        return &amp;quot;&amp;lt;b&amp;gt;&amp;quot; + fn() + &amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
     return wrapped&lt;br /&gt;
&lt;br /&gt;
#定义函数：完成包裹数据&lt;br /&gt;
def makeItalic(fn):&lt;br /&gt;
    def wrapped():&lt;br /&gt;
        print(&amp;quot;----2---&amp;quot;)&lt;br /&gt;
        return &amp;quot;&amp;lt;i&amp;gt;&amp;quot; + fn() + &amp;quot;&amp;lt;/i&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
@makeBold&lt;br /&gt;
@makeItalic&lt;br /&gt;
def test3():&lt;br /&gt;
    print(&amp;quot;----3---&amp;quot;)&lt;br /&gt;
    return &amp;quot;hello world-3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ret = test3()&lt;br /&gt;
print(ret)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[File:Wrapper原理.png|Wrapper原理|50px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Wrapper2.png|Wrapper2|50px]]&lt;br /&gt;
&lt;br /&gt;
==decorator2024 ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION DECORATORS&lt;br /&gt;
Python decorators are a special syntax for functions which take other functions as arguments. Python&lt;br /&gt;
functions are objects, so any function can take a function as an argument. The decorator syntax provides a&lt;br /&gt;
clean and easy way to do this. The basic format of a decorator is:&lt;br /&gt;
&lt;br /&gt;
In [2]: def some_decorator(wrapped_function):&lt;br /&gt;
def wrapper():&lt;br /&gt;
print(&amp;#039;Do something before calling wrapped function&amp;#039;)&lt;br /&gt;
wrapped_function()&lt;br /&gt;
print(&amp;#039;Do something after calling wrapped function&amp;#039;)&lt;br /&gt;
return wrapper&lt;br /&gt;
&lt;br /&gt;
You can define a function and pass it as an argument to this function:&lt;br /&gt;
&lt;br /&gt;
In [3]: def foobat():&lt;br /&gt;
...:&lt;br /&gt;
print(&amp;#039;foobat&amp;#039;)&lt;br /&gt;
...:&lt;br /&gt;
In [4]: f = some_decorator(foobat)&lt;br /&gt;
In [5]: f()&lt;br /&gt;
Do something before calling wrapped function&lt;br /&gt;
foobat&lt;br /&gt;
Do something after calling wrapped function&lt;br /&gt;
&lt;br /&gt;
The decorator syntax simplifies this by indicating which function should be wrapped by decorating it with&lt;br /&gt;
@decorator_name. Here is an example using the decorator syntax with our some_decorator function:&lt;br /&gt;
&lt;br /&gt;
In [6]: @some_decorator&lt;br /&gt;
...: def batfoo():&lt;br /&gt;
...:&lt;br /&gt;
print(&amp;#039;batfoo&amp;#039;)&lt;br /&gt;
...:&lt;br /&gt;
In [7]: batfoo()&lt;br /&gt;
Do something before calling wrapped function&lt;br /&gt;
batfoo&lt;br /&gt;
Do something after calling wrapped function&lt;br /&gt;
&lt;br /&gt;
Now you call your wrapped function using its name rather than the decorator name. Pre-built functions&lt;br /&gt;
intended as decorators are offered both as part of the Python Standard Library (staticMethod,&lt;br /&gt;
classMethod) and as part of third-party packages, such as Flask and Click.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==decorator2025 ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
入门 Python 装饰器最重要的是搞懂两个核心概念：&lt;br /&gt;
&lt;br /&gt;
    函数是对象，可以作为参数传递&lt;br /&gt;
&lt;br /&gt;
    装饰器其实就是一个“返回函数的函数”&lt;br /&gt;
第一步：理解函数是“变量”&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def greet():&lt;br /&gt;
    print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
a = greet  # 把函数赋值给变量&lt;br /&gt;
a()        # 调用函数 -&amp;gt; 输出 Hello!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
二步：函数作为参数传递&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def run(func):&lt;br /&gt;
    func()&lt;br /&gt;
&lt;br /&gt;
def hello():&lt;br /&gt;
    print(&amp;quot;Hi!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
run(hello)  # 输出 Hi!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
第三步：返回函数的函数（闭包）&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def outer():&lt;br /&gt;
    def inner():&lt;br /&gt;
        print(&amp;quot;I am inner!&amp;quot;)&lt;br /&gt;
    return inner&lt;br /&gt;
&lt;br /&gt;
f = outer()&lt;br /&gt;
f()  # 输出 I am inner!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第四步：最简单的装饰器&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def decorator(func):&lt;br /&gt;
    def wrapper():&lt;br /&gt;
        print(&amp;quot;Before&amp;quot;)&lt;br /&gt;
        func()&lt;br /&gt;
        print(&amp;quot;After&amp;quot;)&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@decorator&lt;br /&gt;
def say_hello():&lt;br /&gt;
    print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
say_hello()&lt;br /&gt;
&lt;br /&gt;
输出：&lt;br /&gt;
&lt;br /&gt;
Before&lt;br /&gt;
Hello!&lt;br /&gt;
After&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
总结记忆口诀：&lt;br /&gt;
&lt;br /&gt;
    装饰器 = “外函数包住原函数” + @语法糖&lt;br /&gt;
&lt;br /&gt;
✅ 学习建议：&lt;br /&gt;
阶段	学什么	推荐练习&lt;br /&gt;
新手	会写不带参数的装饰器	打印前后、计时器装饰器&lt;br /&gt;
熟悉函数式编程	理解闭包、*args 和 **kwargs	写带参数的装饰器&lt;br /&gt;
熟悉标准库	掌握 functools.wraps, lru_cache	给函数加缓存、限制调用次数等&lt;br /&gt;
实战	学 Flask/FastAPI/Django 中的装饰器	权限验证、API 日志、限流装饰器等&lt;br /&gt;
&lt;br /&gt;
需要我为你定制一个「装饰器 7 天入门计划」或提供练习题&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@decorator 的作用&lt;br /&gt;
&lt;br /&gt;
@decorator&lt;br /&gt;
def say_hello():&lt;br /&gt;
    print(&amp;quot;Hello&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
等价于：&lt;br /&gt;
&lt;br /&gt;
def say_hello():&lt;br /&gt;
    print(&amp;quot;Hello&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
say_hello = decorator(say_hello)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=参考=&lt;br /&gt;
&lt;br /&gt;
[https://www.zhihu.com/question/26930016 如何理解Python装饰器？]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://www.cnblogs.com/zhiyong-ITNote/p/7384955.html 深入浅出理解python 装饰器]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html Python装饰器学习（九步入门）]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000&lt;br /&gt;
&lt;br /&gt;
[http://book42qu.readthedocs.io/en/latest/python/python-closures-and-decorators.html Python 的闭包和装饰器]&lt;br /&gt;
&lt;br /&gt;
https://segmentfault.com/a/1190000004461404&lt;br /&gt;
&lt;br /&gt;
http://www.cnblogs.com/ChrisChen3121/p/3208119.html&lt;br /&gt;
&lt;br /&gt;
https://www.zhihu.com/question/31792789&lt;br /&gt;
&lt;br /&gt;
http://www.cnblogs.com/zhiyong-ITNote/p/7384955.html&lt;br /&gt;
&lt;br /&gt;
[[category:python]]&lt;/div&gt;</summary>
		<author><name>Evan</name></author>
	</entry>
</feed>