首页 > 其他分享 >装饰器示例

装饰器示例

时间:2023-08-27 11:44:55浏览次数:36  
标签:__ 函数 示例 num print 装饰 def

1. 装饰器语法糖示例

注解形式:

# 1定义一个装饰器(装饰器的本质是闭包)
def check(fn):
    def inner():
        print("请先登陆")
        fn()

    return inner


# 2使用装饰器装饰函数(增加一个登陆功能)
# 解释器遇到@check 会立即执行 comment = check(comment)
@check
def comment():
    print("发表评论")


comment()

真实面目:

 1 # 1. 定义一个装饰器(装饰器的本质是闭包)
 2 def check(fn):
 3     def inner():
 4         print("登陆验证。。。")
 5         fn()
 6 
 7     return inner
 8 
 9 
10 # 需要被装饰的函数
11 def comment():
12     print("发表评论")
13 
14 
15 # 2. 使用装饰器装饰函数(增加一个登陆功能)
16 comment = check(comment)  # comment函数就是被装饰器装饰后的函数
17 
18 # 3. 执行装饰器函数
19 comment()

输出结果:

登陆验证。。。
发表评论

  

一句话总结:利用闭包特点、不改变函数源码,为其执行前后添加功能。

2. 装饰有参数的函数

 1 # 1. 定义装饰器
 2 def logging(fn):  # fn = sum_num,如果只有1个参数,此参数的实参必须是被修饰函数
 3     def inner(a, b):  # 内部函数的参数列表,必须直接或间接包含被装饰的参数列表
 4         print("被装饰函数执行之前")
 5         fn(a, b)
 6         print("被装饰函数执行之后")
 7 
 8     return inner  # sum_num = inner
 9 
10 
11 # 2. 使用装饰器装饰函数
12 @logging
13 def sum_num(a, b):
14     result = a + b
15     print(result)
16 
17 
18 # 3. 执行被装饰函数验证
19 sum_num(1, 2)  # 输出结果是3

执行结果:

被装饰函数执行之前
3
被装饰函数执行之后

总结:

1. 装饰器就是闭包

2. 装饰器的外部函数的参数的实参必须是被装饰函数

3. 内部函数的参数直接或间接包含被装饰函数的列表

3. 装饰有返回值的函数

 1 # 1. 定义装饰器
 2 def logging(fn):  # fn = sum_num,如果只有1个参数,此参数的实参必须是被修饰函数
 3     def inner(a, b):
 4         print("被装饰函数执行之前")
 5         result = fn(a, b)  # 内部函数的参数列表,必须直接或间接包含被装饰的参数列表
 6         print(f"被装饰函数执行之后,结果为:{result}")
 7         return result
 8 
 9     return inner  # sum_num = inner
10 
11 
12 # 2. 使用装饰器装饰函数
13 @logging
14 def sum_num(a, b):
15     result = a + b
16     return result
17 
18 
19 # 3. 执行被装饰函数验证
20 result = sum_num(1, 2)
21 print(result)

执行结果:

被装饰函数执行之前
被装饰函数执行之后,结果为:3
3

  

总结:跟其他装饰器的使用,没有区别,要是有区别,就是内部函数必须有返回值,返回值为装饰函数的执行结果。

 4. 装饰带有不确定参数的函数

 1 # 定义装饰器
 2 def logging(fn):  # fn = sum_num
 3     def inner(*args, **kwargs):
 4         print("被装饰函数执行之前")
 5         fn(*args, **kwargs)
 6         print("被装饰函数执行之后")
 7 
 8     return inner  # sum_num = inner
 9 
10 
11 # 使用装饰器装饰函数
12 @logging
13 def sum_num(*args, **kwargs):
14     print(args, kwargs)
15 
16 
17 sum_num(1, 2, 3, age="18")

输出:

被装饰函数执行之前
(1, 2, 3) {'age': '18'}
被装饰函数执行之后

  

 1 # 定义装饰器
 2 def logging(fn):  # fn = sum_num
 3     def inner(*args, **kwargs):
 4         print("被装饰函数执行之前")
 5         result = fn(*args, **kwargs)
 6         print("被装饰函数执行之后")
 7         return result
 8 
 9     return inner  # sum_num = inner
10 
11 # 使用装饰器装饰函数
12 @logging
13 def sum_num(*args, **kwargs):
14     print(args, kwargs)
15 
16 
17 sum_num(1, 2, 3, age="18")

5. 多个装饰器装饰一个函数

 1 # 定义装饰器1
 2 def check1(fn1):
 3     def inner1():
 4         print("登陆验证1")
 5         fn1()
 6 
 7     return inner1
 8 
 9 
10 # 定义装饰器2
11 def check2(fn2):
12     def inner2():
13         print("登陆验证2")
14         fn2()
15 
16     return inner2
17 
18 # 被装饰器的函数
19 
20 @check1
21 @check2
22 def comment():
23     print("发表评论")
24 
25 
26 comment()

输出:

登陆验证1
登陆验证2
发表评论

  

6. 类装饰器

前提:需要掌握__init__、__call__ 2个内置函数。__init__函数用于类对象的初始化。当一个类的实例被像函数一样调用时,__call__ 方法会被调用。

1 # 定义一个类,实现__call__方法
2 class Check(object):
3     def __call__(self, *args, **kwargs):
4         print("我是call方法")
5 
6 c = Check()
7 c()

当执行到“对象()”即c()时,会自动咨询__call__方法。输出:我是call方法

 

动态行为修改:在特定条件下,可以通过动态修改 __call__ 方法来改变类的实例的行为。

 1 class DynamicBehavior:
 2     def __call__(self, *args, **kwargs):
 3         if 'override' in kwargs:
 4             print("动态修改行为")
 5         else:
 6             print("默认行为")
 7 
 8 
 9 dyn = DynamicBehavior()
10 dyn()  # 输出:默认行为
11 dyn(override=True)  # 输出:动态修改行为
默认行为
动态修改行为

  

类装饰器是一种特殊类型的装饰器,它使用类而不是函数来装饰其他函数或类。类装饰器可以通过定义 __call__ 方法来实现调用。

最佳实践:

  1. 创建一个类装饰器时,需要确保它的 __init__ 方法接受被装饰的函数或类作为参数。
  2. 在 __call__ 方法中实现装饰器逻辑,并返回一个新的函数或类。
  3. 使用 @ 符号将类装饰器应用到要装饰的对象上。
 1 # 1. 定义类装饰器
 2 class MyDecorator:
 3     def __init__(self, decorated):  # 1. __init__必须有函数形参,实参是被装饰的函数
 4         self.decorated = decorated
 5 
 6     def __call__(self, *args, **kwargs):  # 2. 装饰逻辑写在__call__中
 7         # 在调用被装饰的函数之前执行一些操作
 8         print("Before function execution")
 9 
10         # 调用被装饰的函数
11         result = self.decorated(*args, **kwargs)
12 
13         # 在调用被装饰的函数之后执行一些操作
14         print("After function execution")
15 
16         return result  # 如果被修饰函数有返回值就用此句,如果没有,省略此句
17 
18 
19 @MyDecorator
20 def my_function():
21     print("Inside my_function")
22 
23 
24 my_function()

输出结果:

Before function execution
Inside my_function
After function execution

  

 

标签:__,函数,示例,num,print,装饰,def
From: https://www.cnblogs.com/allenxx/p/17659847.html

相关文章

  • 装饰器
    定义给已有函数增加额外功能的函数。其本质上就是一个闭包函数。特点1. 不修改已有函数的源代码(无风险)2. 不修改已有函数的调用方式(无风险)3. 给已有函数增加额外的功能(只需要关注额外增加的部分)语法1.定义一个装饰器2.在目标函数上使用装饰器通过@装饰器名称放在......
  • 【补充】装饰类的装饰器类作为装饰器
    【一】装饰类的装饰器:装饰类的装饰器是指一个类,它接收一个类作为参数,并返回一个新的类。这个新的类通常会继承自被装饰的类,并对其进行一些拓展或修改。示例代码如下:defdecorator(cls):classNewClass(cls):def__init__(self,*args,**kwargs):......
  • 上海KTV酒店装饰电镀卡通不锈钢积木熊雕塑厂家报价
    上海KTV酒店装饰电镀卡通不锈钢积木熊雕塑厂家报价Bearbrick卡通不锈钢积木熊雕塑是一个独特的塑料玩具,它的形象是一个可爱的、独特的拟人化熊公仔,带有大肚皮。卡通不锈钢积木熊雕塑虽然是一个简单的塑料玩具,但世界上一些最大的时装公司和设计师已经采用它来展示他们最新的设计和......
  • 一个简单的spdlog使用示例
    目录引用源码封装Log头文件使用方法spdlog是一个开源、跨平台、无依赖、只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://github.com/gabime/spdlog。引用源码先下载spdlog的源码,将源码的include文件夹复制到自己的项目文件夹下:然后在项......
  • 【算法-二分查找】实现过程、C++代码示例以及实际应用
    二分查找简介:也称为折半查找,是一个在已排序数组中查找特定元素的搜索算法。它的工作原理是将有序数组分成两半,然后检查目标值是在左半部分还是右半部分,然后在所选择的那部分中继续查找。这一过程将不断地重复,直到找到目标值或确定目标值不在数组中。实现过程:1.初始化两个指针:lo......
  • WPF-利用装饰器实现空间的自由拖动
    在项目中经常会遇到类似如下要求的需求,创建允许自由拖动的控件,这样的需求可以使用WPF的装饰器Adorner来实现。 一、什么是装饰器?装饰器是一种特殊类型的FrameworkElement,装饰器始终呈现在被装饰元素的顶部,用于向用户提供可视化提示。装饰器可以在不改变原有控件结构的基......
  • linux docker公网源下载示例
    1.get-docker.sh百度一下,进入docker官网直接下载该文件,然后执行即可2.直接下载repo文件示例:wgethttps://download.docker.com/linux/centos/docker-ce.repo-O/etc/yum.repos.d/docker.sh--no-check或者yum-config-manager--add-repohttps://download.docker.com/lin......
  • Angular:表单设置动态校验规则(ngZorro示例)
    背景有时我们需要根据不同的条件,决定表单控件是否是必填的。代码示例HTML文件<formnz-form[formGroup]="validateForm"(ngSubmit)="submitForm()"><nz-form-item><nz-form-label[nzSpan]="4"nzRequirednzFor="name">Name</nz-f......
  • 论文解读 | 解释和利用对抗性示例
    原创|文BFT机器人摘要ABSTRACT这篇论文研究了神经网络和其他机器学习模型在错误分类对抗性示例方面的问题。对抗性示例是通过对数据中的示例应用微小但故意的扰动来生成的,导致模型输出错误答案。以往的解释主要集中在非线性和过拟合上,然而,本文提出了一种不同的观点,认为神经网络......
  • 福建学校草坪装饰镜面不锈钢风车雕塑厂家报价
    福建学校草坪装饰镜面不锈钢风车雕塑厂家报价不锈钢风车雕塑不仅是风景,更是精神象征和图腾。正如欧洲流传的一句话:上帝创造了人,荷兰风车创造了陆地。风车象征着荷兰的民族文化,人们对天空的热爱,童话般的幸福。风车在西班牙随处可见。风车虽然失去了原有的功效,但却象征着西班牙农业的......