Fork me on GitHub

装饰器: ''' 装饰器:在不改变原有代码的情况下,为该原函数扩展新功能 特征:返回新函数,替换旧函数 语法:@ (语法糖)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# ### 装饰器:
'''
装饰器:在不改变原有代码的情况下,为该原函数扩展新功能
特征:返回新函数,替换旧函数
语法:@ (语法糖)
'''
 
# (1) 装饰器原型:
def kuozhan(func):
    def newfunc():
        print("厕所前,屁滚尿流")
        func()
        print("厕所后,站不起来")
    return newfunc
 
 
def func():
    print("我是个屌丝")
 
# 手动的 把新函数 赋值给 旧函数
func = kuozhan(func) # res = newfunc
func() #newfunc()
 
# (2) 装饰器@
print("<=-===>")
def kuozhan(func):
    def newfunc():
        print("厕所前,风流倜傥")
        func()
        print("厕所后,面黄肌瘦")
    return newfunc
 
@kuozhan
def func():
    print("我是一个高富川")
 
'''
第一步: 先把下面的func当成参数传递给kuozhan
第二部:把返回的新函数重新赋值给func
* 谁跟在@ 这个装饰器的下面,就会自动把谁当成参数传递
func = kuozhan(func)
'''
func()
 
# (3) 互相嵌套的装饰器函数
def kuozhan1(func):
    def newfunc():
        print("厕所前,蓬头垢面1")
        func()
        print("厕所后,精神抖擞2")
    return newfunc
 
def kuozhan2(func):
    def newfunc():
        print("吃饭前,洗洗手3")
        func()
        print("吃饭后,洗洗脚4")
    return newfunc
 
@kuozhan2
@kuozhan1
def func():
    print("我是一个白富美5")
 
func() # 3 1 5 2 4
 
# (4) 带有参数的装饰器
"""
原函数在扩展之前是几个参数,那么扩展之后也相应有几个参数
"""
def kuozhan(func):
    def newfunc(who,where):
        print("厕所前,干净整洁")
        func(who,where)
        print("厕所后,臭气熏天")
    return newfunc
 
@kuozhan
def func(who,where):
    print('{}在{}解手'.format(who,where))
 
func("马军强","鸟窝")
 
# (5) 带有参数返回值的装饰器
'''通过装饰器改造之后,原函数返回什么,新函数返回什么'''
def kuozhan(func):
    def newfunc(*args,**kwargs):
        print("厕所前,萎靡不振")
        res = func(*args,**kwargs)  #"电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨"
        print("厕所后,兽性大发")
        return res
         
         
    return newfunc
     
@kuozhan
def func(*args,**kwargs):
    print(args)
    for i in args:
        print("茅厕的地点在:",i)
    # print(kwargs)
    dic = {'jzn':"境泽年","ys":"易思","hw":"黄文","sc":"舒畅"}
     
    '''
    lst = []
    for k,v in kwargs.items():
        # 如果k在dic这个字典里,说明这个字典存在这个键,然后我就通过键取值
        if k in dic:           
            lst.append("{} 留下了黄金 {}".format(dic[k],v)) 
    '''
     
    lst = ["{} 留下了黄金 {}".format(dic[k],v) for k,v in kwargs.items() if k in dic ]
    return lst
 
     
res = func("电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨")
print("<112233>")
print(res)
 
 
"""
* 和 ** 的魔术用法(函数的调用处)
def func(a,b,c):
    print(a,b,c)
func(*[1,2,3])
 
def func(a=1,b=2,c=3,*,d=4):
    print(a,b,c)
func(**{"a":3,"b":4,"c":5,"d":6})#func(a=3,b=4,c=5,d=6)
"""
 
# (6) 用类装饰器修饰原函数
class MyClass():
 
    def __call__(self,func):
        return self.kuozhan2(func)
 
    def kuozhan1(func):
        def newfunc():
            print("厕所前,饥肠辘辘")
            func()
            print("厕所后,酒足饭煲")
        return newfunc
         
    def kuozhan2(self,func):
        def newfunc():
            print("厕所前,茶饭不思")
            func()
            print("厕所后,满口雌黄")
        return newfunc
 
# 方法一
"""
@MyClass.kuozhan1
def func():
    print("厕所进行时... ... ")
func()
"""
 
# 方法二
@MyClass()   #@obj => obj(func)
def func():
    print("厕所进行时... ... ")
 
func()
 
'''
先把@符号右边的值算出来,在通过@符号把下面的函数当成参数进行传递
@MyClass()  就相当于 @obj
把func当成参数传递给obj => obj(func)
obj当成一个函数在进行调用,自动触发__call__魔术方法
return newfunc
func = newfunc
func()  就相当于 newfunc()
'''
 
 
# (7) 带有参数的函数装饰器
def outer(num):
    def kuozhan(func):
        def newfunc1(self):
            print("厕所前,老实巴交")
            func(self)
            print("厕所后,长牙舞爪")
         
        def newfunc2(self):
            print("厕所前,衣冠楚楚")
            func(self)
            print("厕所前,衣冠禽兽")
             
        if num == 1:
            return newfunc1
        elif num == 2:
            return newfunc2
        elif num == 3:
            return "今天天气好晴朗哦"
    return kuozhan
             
 
class MyClass():
 
    @outer(1
    def func1(self):
        print("向前一小步")
         
    @outer(2)
    def func2(self):
        print("文明一大步")
         
    @outer(3)
    def func3(self):
        print("来也冲冲,去也冲冲")
 
print("<===>")
obj = MyClass()
obj.func1()
print("<===>")
obj.func2()
print("<===>")
print(obj.func3)
 
'''
outer(1) => 返回 kuozhan 函数
@kuozhan
func1
 
@符号开始发挥作用
把func1当成参数进行传递,传给kuozhan中的func进行接收
根据num 这个值进行判断 , 返回newfunc1
obj.func1 = newfunc1
obj.func1() <===> newfunc1()
 
 
@outer(2) => 返回 kuozhan 函数
@kuozhan
func3
@符号开始发挥作用
把func3当成参数进行传递,传给kuozhan中的func进行接收
obj.func3 = "今天天气好晴朗哦"
print(该值) [因为函数名可以作为变量使用.]
'''
 
# (8) 带有参数的类装饰器
"""
如果传递的参数是1,我就为该类,添加成员属性和方法
如果传递的参数是2,我就把该类当中的run方法变成属性
"""
class Kuozhan():
    ad = "贵族茅厕,欢迎您来,欢迎您在来"
    def __init__(self,num):
        self.num = num
 
    def __call__(self,cls):
        if self.num == 1:
            return self.kuozhan1(cls) #newfunc 返回
             
        elif self.num == 2:
            return self.kuozhan2(cls)
    def money(self):
        print("贵族茅厕收费标准,每小时10元,包月1400")
             
    def kuozhan1(self,cls):
        def newfunc():
            # 添加成员属性
            cls.ad = Kuozhan.ad
            # 添加成员方法
            cls.money = Kuozhan.money
            return cls()
             
        return newfunc
         
    def kuozhan2(self,cls):
        def newfunc():
            # 先来判断run方法是否在cls当中
            if "run" in cls.__dict__:
                #调用一个类中得run方法拿到返回值"亢龙有悔"
                res = cls.run()
                #成员属性run 从方法变成属性,值替换了
                cls.run = res  # 把"亢龙有悔"进行替换赋值给run成员属性
            return cls()
        return newfunc
         
 
@Kuozhan(1#@obj => obj(MyClass)
class MyClass():
    def run():
        return "亢龙有悔"
 
obj = MyClass()
print(obj.ad)
obj.money()
"""
Kuozhan(1) => obj  自动触发init方法,存储num =>self.num = num
@obj
@符发挥作用把MyClass当成一个参数传递给obj => obj(MyClass)
触发__call__魔术方法,最后将newfunc进行返回
MyClass = newfunc  以前是类 现在是函数
obj = MyClass() <===>  newfunc()
obj = cls() # cls() 是一个对象 是以前MyClass 这个类的对象
"""
 
@Kuozhan(2)
class MyClass():
    def run():
        return "亢龙有悔"
 
obj = MyClass()
print(obj.run)
 
print("<==========================================================>")
# 外面全局的abc 与 函数内部局部的abc 两者不发生冲突,彼此独立
class abc():   
    =19
     
def func(cls):
    cls.b = 20
    return cls
     
     
obj2 = func(abc)
print(abc().a)
abc =  99988777
print(abc)
 
 
print(obj2.b)
print(obj2.a)

  

posted @   MR_黄Python之路  阅读(565)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· 软件产品开发中常见的10个问题及处理方法
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· MQ 如何保证数据一致性?
· 《HelloGitHub》第 108 期
点击右上角即可分享
微信分享提示