Python3中装饰器介绍

2023-11-11

      Python中的装饰器(decorator)是一个接受另一个函数作为参数的函数。装饰器通常会修改或增强它接受的函数并返回修改后的函数。这意味着当你调用一个装饰函数时,你会得到一个与基本定义相比可能有一些额外特性的函数。Python中的函数可以用作或作为参数传递。

      Python中的装饰器允许程序员修改函数或类的行为。装饰器允许我们包装一个函数以扩展此函数的行为而无需修改此函数。

      在Python中,装饰器以@符号开头,后跟我们将用来”装饰”的函数名称。要使用装饰器,你只需将它放在函数定义之前的行上。@符号是装饰器的语法糖

      装饰器不仅可以是函数,还可以是类。使用类装饰器主要依靠类的__call__方法。一个函数可以同时定义多个装饰器。

      Python自带几个内置装饰器:@classmethod;@staticmethod;@property

      Python中的函数属性:函数是Object类型的一个实例;你可以将函数存储在变量中;你可以将一个函数作为参数传递给另一个函数;你可以从一个函数内返回另一个函数;你可以将函数存储在哈希表、列表等数据结构中。

      以上内容及以下测试代码主要参考:

      https://python101.pythonlibrary.org/chapter25_decorators.html 

      https://www.geeksforgeeks.org/decorators-in-python/ 

import functools

var = 8

def another_function(func):
    """ A function that accepts another function """
    def other_func(): # 嵌套函数
        val = "The result of %s is %s" % (func(), eval(func()))
        return val
    return other_func

if var == 1:
    # reference: https://python101.pythonlibrary.org/chapter25_decorators.html
    def a_function():
        """ A pretty useless function """
        return "1+1"

    value = a_function()
    print(value)
    decorator = another_function(a_function)
    print(decorator())
elif var == 2:
    # 对以上示例做些修改,加入装饰器 https://python101.pythonlibrary.org/chapter25_decorators.html
    @another_function # 这里的@称为语法糖
    def a_function():
        """ A pretty useless function """
        return "1+1"

    value = a_function()
    print(value)
elif var == 3:
    # reference: https://python101.pythonlibrary.org/chapter25_decorators.html
    class DecoratorTest(object):
        """ Test regular method vs @classmethod vs @staticmethod """

        def __init__(self):
            """ Constructor """
            pass

        def doubler(self, x):
            """"""
            print("running doubler")
            return x*2

        @classmethod # 可以使用类的实例或直接由类本身作为其第一个参数来调用
        def class_tripler(klass, x):
            """"""
            print("running tripler: %s" % klass)
            return x*3

        @staticmethod # 类中的一个函数,可以在实例化类或不实例化类的情况下调用它
        def static_quad(x):
            """"""
            print("running quad")
            return x*4

    decor = DecoratorTest()
    print(decor.doubler(5))
    print(decor.class_tripler(3))
    print(DecoratorTest.class_tripler(3))
    print(DecoratorTest.static_quad(2))
    print(decor.static_quad(3))

    print(decor.doubler)
    print(decor.class_tripler)
    print(decor.static_quad)
elif var == 4:
    # https://python101.pythonlibrary.org/chapter25_decorators.html
    class Person(object):

        def __init__(self, first_name, last_name):
            """Constructor"""
            self.first_name = first_name
            self.last_name = last_name

        @property # 将类方法转换为属性
        def full_name(self):
            """ Return the full name """
            return "%s %s" % (self.first_name, self.last_name)

    person = Person("Mike", "Driscoll")
    print(person.full_name) # 注意: person.full_name与person.full_name()区别
    print(person.first_name)
    #person.full_name = "Jackalope" # AttributeError: can't set attribute, 不能将属性设置为不同的值,只能间接进行
    person.first_name = "Dan"
    print(person.full_name)
elif var == 5:
    # reference: https://www.geeksforgeeks.org/decorators-in-python/
    def shout(text):
        return text.upper()

    yell = shout # assign the function shout to a variable
    print(yell('Hello'))

    def greet(func): # greet function takes another function as a parameter
        greeting = func("""Hi, I am created by a function passed as an argument.""") # storing the function in a variable
        print (greeting)

    greet(shout)

    def create_adder(x):
        def adder(y):
            return x+y

        return adder # function can return another function

    add_15 = create_adder(15)
    print(add_15(10))
elif var == 6:
    # reference: https://www.geeksforgeeks.org/decorators-in-python/
    def hello_decorator(func): # defining a decorator
        # inner is a Wrapper function in which the argument is called
        # inner function can access the outer local functions like in this case "func"
        @functools.wraps(func) # 内置装饰器@functools.wraps会保留原函数的元信息,将元信息拷贝到装饰器里面的func函数中
        def inner():
            print("Hello, this is before function execution:", func.__name__) # 函数对象的__name__属性,可以拿到函数的名字

            func() # calling the actual function now inside the wrapper function.
            print("This is after function execution")

        return inner

    # defining a function, to be called inside wrapper
    def function_to_be_used():
        print("This is inside the function !!")

    print("decorator before, function name:", function_to_be_used.__name__)
    function_to_be_used() # 装饰器前

    # passing 'function_to_be_used' inside the decorator to control its behavior
    function_to_be_used = hello_decorator(function_to_be_used)
    # 注意:如果上面inner函数定义前不加@functools.wraps,下面的print将输出inner,添加后会输出function_to_be_used
    print("decorator after, function name:", function_to_be_used.__name__)
    function_to_be_used() # 装饰器后

    # above code is equivalent to
    print("==========================")
    @hello_decorator
    def function_to_be_used2():
        print("This is inside the function !!")

    function_to_be_used2()
elif var == 7:
    # reference: https://www.geeksforgeeks.org/decorators-in-python/
    def hello_decorator(func):
        # The inner function takes the argument as *args and **kwargs which means
        # that a tuple of positional arguments or a dictionary of keyword arguments can be passed of any length
        # This makes it a general decorator that can decorate a function having any number of arguments
        @functools.wraps(func)
        def inner(*args, **kwargs): # *args表示所有的位置参数,**kwargs表示所有的关键字参数.之后再将其传到func函数中,这样保证了能完全传递所有参数
            print("before Execution")

            print("call function:", func.__name__)
            returned_value = func(*args, **kwargs) # getting the returned value
            print("after Execution")

            return returned_value # returning the value to the original frame

        return inner

    # adding decorator to the function
    @hello_decorator
    def sum_two_numbers(a, b):
        print("Inside the function")
        return a + b

    a, b = 1, 2

    # getting the value through return of the function
    print("Sum =", sum_two_numbers(a, b))
elif var == 8:
    class decorator:
        def __init__(self, func):
            self.func = func

        def __call__(self, *args, **kwargs):
            print("function name:", self.func.__name__)
            return self.func(*args, **kwargs)

    @decorator
    def add(a, b):
        print("add value:", a+b)

    add(2, 3)

print("test finish")

GitHubhttps://github.com/fengbingchun/Python_Test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python3中装饰器介绍 的相关文章

随机推荐

  • L2-4 哲哲打游戏PTA

    哲哲是一位硬核游戏玩家 最近一款名叫 达诺达诺 的新游戏刚刚上市 哲哲自然要快速攻略游戏 守护硬核游戏玩家的一切 为简化模型 我们不妨假设游戏有 N 个剧情点 通过游戏里不同的操作或选择可以从某个剧情点去往另外一个剧情点 此外 游戏还设置了
  • Linux网络程序设计-TCP网络编程

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 TCP IP协议是什么 二 端口 三 socket端口 1 两个重要的数据类型sockaddr和sockaddr in 2 基于TCP协议的客户端 服务器
  • GitHub 优秀的 Android 开源项目第二篇——转自多篇网络文章

    原文地址为http www trinea cn Android android open source projects view 作者Trinea 主要介绍那些不错个性化的View 包括ListView ActionBar Menu Vi
  • weex scroller滚动的小烦恼

    背景 前几天的需求开发中 需要完成这样一个功能 这还不简单 一个横向滚动的tag选择功能 一个横向scroller搞定问题 但是做为一个对自己有 要求 的程序员 怎么可能会接受一个死气沉沉的滚动条 为了勾起用户的点击欲望 我毫不犹豫的增加了
  • 微信开发提示未绑定网页开发者

    加入一下就可以了
  • input上边框有阴影(iPhone手机)

    做移动端 发现在苹果手机上input显示有问题 上边框一直有阴影 input的border初始化 box shadow也做了处理 box shadow 0 0 0 fff 在手机端都无效 如图 解决方案 input outline none
  • 利用cuda加速MATLAB程序

    利用cuda加速MATLAB程序 利用cuda加速MATLAB程序 1参考木子超的办法 2参考Tomheaven的方法 3引用 最近因为要做张量的模态积 所以要考虑使用cuda来进行并行的编程 但是c 实在太麻烦 尤其是在有MATLAB的时
  • HBase Shell常用Shell命令

    1 进入与退出hbase shell命令行窗口 root repo hbase shell hbase main 001 0 gt hbase main 001 0 gt exit root repo 2 help 1 查看hbase中有哪
  • 光标异常如何解决

    相信大家都遇到过一个小问题 那就是当编辑文章时光标会不小心变为下图所示的样子 这样就无法正常删除文字 其实想要恢复正常很简单只需点进编辑页面后 再按下insert键即可 一般电脑是Ins
  • GitHub项目:自然语言处理领域的相关干货整理

    自然语言处理 NLP 是计算机科学 人工智能 语言学关注计算机和人类 自然 语言之间的相互作用的领域 本文作者为NLP初学者整理了一份庞大的自然语言处理领域的概览 选取的参考文献与资料都侧重于最新的深度学习研究成果 这些资源能为想要深入钻研
  • sql关于avg中的else null和else 0

    drop table test1 use sys create table test1 id int not null num int not null insert into test1 values 1 10 insert into t
  • Eclipse 配置 maven

    旧版的eclipse在线安装maven太麻烦了 要安装很多依赖的东西 有时费半天劲 还按不上 不是缺这个就缺那个 而且网上推荐maven插件链接http m2eclipse sonatype org sites m2e已经失效 查看其官方网
  • Kutools for Excel v26.10 Excel插件工具箱中文版

    Kutools for Excel 是一款强大的Excel 插件增强工具箱 可以在Excel中点击几下简化各种复杂的任务 例如 Excel用户可以轻松地将工作表与多次点击相结合 合并单元格而不会丢失数据 仅粘贴到可见单元格 等等 毫无疑问
  • Kafka3.1安装配置,配置Kafka集群,Zookeeper集群

    1 下载Kafka安装包 Kafka官网下载地址 https kafka apache org downloads 2 解压压缩包 tar zxvf kafka 2 12 3 1 0 tgz c kafka 3 进入配置文件目录 cd ka
  • mybatis3 大于、小于、不等于等特殊字符转义

    特殊字符 特殊字符转义一 特殊字符转义二 gt gt lt lt 代码实例
  • day22-----3.1-----coturn安装以及报错“coturn/src/apps/relay/netengine.c:316:对‘SSL_CTX_up_ref’未定义的引用“

    1 安装步骤 我的系统是Ubuntu16 04 1 1 安装coturn需要的依赖 我先安装了下面两个依赖 sudo apt get install libssl dev sudo apt get install libevent dev
  • ajax提交进度条,ajax上传进度条onprogress

    ajax上传进度条onprogress 2020 10 15 分类 前端资源 主要还是用到XMLhttprequest的onprogress监听函数实现 var formData new FormData formData append f
  • uniapp选择地址弹窗组件

    1 效果 2 子组件在components里面创建组件AddreessWindow
  • DP1.4协议学习(三)Main-Link链路上的同步传输服务

    上一篇文章讲到Main link链路服务就是用来传输音视频数据的 本篇文章将具体探究一个完整的Main link传输服务具体需要做哪些工作 在Main link的同步传输服务中需要明确一下问题 Main Link具体传输哪些数据 数据格式应
  • Python3中装饰器介绍

    Python中的装饰器 decorator 是一个接受另一个函数作为参数的函数 装饰器通常会修改或增强它接受的函数并返回修改后的函数 这意味着当你调用一个装饰函数时 你会得到一个与基本定义相比可能有一些额外特性的函数 Python中的函数可