python装饰器详解-python中的装饰器详解

2023-05-16

在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介

因为在python里面,函数也是对象,也可以作为参数进行传递.python装饰器本质也是一种特殊函数,它接收的参数是函数对象,然后动态地函数参数添加额外的功能,而不用修改原有的函数对象.python装饰器传入的参数是函数,返回的值也是函数!

python装饰器思想有点类似设计模式的装饰模式, 其意图是动态地给函数对象添加额外的功能.比如像增加日志打印的功能,有点面向切面编程(AOP)的感觉.

装饰器语法

以@开头,接着后面跟着的是装饰器的名字和可选的参数.装饰器语法是一种语法糖.

格式如下

复制代码 代码如下:

@decomaker(deco_args)

def foo(func_opt_args)

可以组合,等价于foo = g(f(foo))

复制代码 代码如下:

@g

@f

def foo():

statement

简单装饰器

实例

复制代码 代码如下:

#!/usr/bin/python

def deco(func):

print 'start'

func()

print 'end'

return func

@deco

def foo():

print 'In foo'

foo()

foo()

输出

复制代码 代码如下:

start

In foo

end

In foo

In foo

带内嵌函数装饰器

内嵌函数保证每次新函数都被调用.而且被装饰的函数可以带有参数.

实例

复制代码 代码如下:

def deco(func):

def _deco(x): #该函数为内嵌函数

print 'start'

func(x)

print 'end'

return _deco

@deco

def foo(x):

print 'In foo, get value is: %d' % x

foo(123456)

输出:

复制代码 代码如下:

start

In foo, get value is: 123456

end

带参数的装饰器

需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用 deco_args 做了些事并返回函数对象,而该函数对象正是以 foo 作为其参数的装饰器。简单的说来:foo=decomaker(deco_args)(foo)

实例

复制代码 代码如下:

def deco(arg):

def wrapper1(func):

def _deco(x):

print "get type is: ", arg

func(x)

return _deco

def wrapper2(func):

def _deco(x):

func(x)

print "get type is: ", arg

return _deco

if arg == 'type1':

return wrapper1

else:

return wrapper2

@deco("type2")

def foo(x):

print 'In foo: ', x

foo(123)

输出

复制代码 代码如下:

In foo: 123

get type is: type2

总结

装饰器本质是高阶的函数,可以装饰其他函数,增加被装饰函数的功能,但不能覆盖或改变被装饰函数原有的行为.对于被装饰的函数来说,装饰器是透明的.装饰器传入参数为函数,返回的函数是被装饰的函数.最后我们来实现给一个函数添加打印日志的功能,而不用改变这个函数.

复制代码 代码如下:

#!/usr/bin/python

#coding=utf-8

import functools

def log(prefix, suffix):

def deco(func):

@functools.wraps(func)

def wrapper(*args, **kargs):

print '%s log start' % prefix

print('get a is: %s' % args[0])

print('get b is: %s' % args[1])

print('get c is: %s' % args[2])

print('get d is: %s' % kargs['d'])

print('get d is: %s' % kargs['f'])

func(*args, **kargs)

print '%s log end' % suffix

return wrapper

return deco

@log('logstart', 'logend')

def test(a, b, c, d, f):

print 'call func name is: %s' % test.__name__

test(1, 2, 3, d = 'dddd', f = 'ffff')

输出:

复制代码 代码如下:

logstart log start

get a is: 1

get b is: 2

get c is: 3

get d is: dddd

get d is: ffff

call func name is: test

logend log end

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

python装饰器详解-python中的装饰器详解 的相关文章

  • xlrd.biffh.XLRDError:Excel xlsx 文件;不支持[重复]

    这个问题在这里已经有答案了 我正在尝试使用读取启用宏的 Excel 工作表pandas read excel与 xlrd 库 它在本地运行良好 但是当我尝试将其推送到 PCF 时 我收到此错误 2020 12 11T21 09 53 441
  • 从Python中的字符串中提取货币金额

    我正在制作一个程序 从字符串中获取货币并将其转换为其他货币 例如 如果字符串是 the car cost me 13 250 我需要得到 and 13250 我已经有了这个正则表达式 1 确实如此 但是该字符串很有可能有多个价格 并且全部使
  • boto3 资源(例如 DynamoDB.Table)的类型注释

    The boto3库提供了几种返回资源的工厂方法 例如 dynamo boto3 resource dynamodb Table os environ DYNAMODB TABLE 我想注释这些资源 以便我可以获得更好的类型检查和完成 但我
  • Python在postgresql表中查找带有单引号符号的字符串

    我需要从 psql 表中查找包含多个单引号的字符串 我当前的解决方案是将单引号替换为双单引号 如下所示 sql query f SELECT exists SELECT 1 FROM table name WHERE my column m
  • 将 numpy 数组写入文本文件的速度

    我需要将一个非常 高 的两列数组写入文本文件 而且速度非常慢 我发现如果我将数组改造成更宽的数组 写入速度会快得多 例如 import time import numpy as np dataMat1 np random rand 1000
  • TF map_fn 或 while_loop 用于不同形状的张量列表

    我想处理不同形状的张量序列 列表 并输出另一个张量列表 考虑每个时间戳上具有不同隐藏状态大小的 RNN 就像是 输入 tf ones 1 2 2 tf ones 2 2 3 tf ones 3 2 1 输出 tf zeros 1 2 4 t
  • Tweepy StreamListener 到 CSV

    我是 python 新手 我正在尝试开发一个应用程序 使用 Tweepy 和 Streaming API 从 Twitter 检索数据并将数据转换为 CSV 文件 问题是此代码不会创建输出 CSV 文件 也许是因为我应该将代码设置为在实现例
  • 了解 Python 中的酸洗

    我最近接到一项作业 需要以腌制形式放置一本字典 其中每个键引用一个列表 唯一的问题是我不知道腌制形式是什么 谁能给我指出一些好的资源的正确方向来帮助我学习这个概念 pickle 模块实现了一个基本但强大的算法 用于序列化和反序列化 Pyth
  • 根据开始列和结束列扩展数据框(速度)

    我有一个pandas DataFrame含有start and end列 加上几个附加列 我想将此数据框扩展为一个时间序列 从start值并结束于end值 但复制我的其他专栏 到目前为止 我想出了以下内容 import pandas as
  • 如何在 Python 3 中循环遍历集合,同时从集合中删除项目

    这是我的情况 我有一个list set 哪个并不重要 movieplayer我想调用的对象 preload 功能开启 该预加载函数可以立即返回 但希望将来返回一点 我想存储这个电影播放器 集合 表明它们尚未预加载 然后循环它们 调用prel
  • 使用 scipy curve_fit 拟合噪声指数的建议?

    我正在尝试拟合通常按以下方式建模的数据 def fit eq x a b c d e return a 1 np exp x b c np exp x d e x np arange 0 100 0 001 y fit eq x 1 1 1
  • 动态 __init_subclass__ 方法的参数绑定

    我正在尝试让类装饰器工作 装饰器会添加一个 init subclass 方法到它所应用的类 但是 当该方法动态添加到类中时 第一个参数不会绑定到子类对象 为什么会发生这种情况 举个例子 这是可行的 下面的静态代码是我试图最终得到的示例 cl
  • 如何使用 Django 项目设置 SQLite?

    我已阅读 Django 文档 仅供参考 https docs djangoproject com en 1 3 intro tutorial01 https docs djangoproject com en 1 3 intro tutor
  • 与 while 循环一样,如何跳过 for 循环中的步骤?

    我尝试像 while 循环一样跳过 for 循环中的几个步骤 在 while 循环中 步骤根据特定条件进行调整 如下面的代码所示 i 0 while i lt 10 if i 3 i 5 else print i i i 1 result
  • 解析根元素内元素之间的 XML 文本

    我正在尝试用 Python 解析 XML 以下是 XML 结构的示例 a aaaa1 b bbbb b aaaa2 a
  • Python 声音(“铃声”)

    我想让一个 python 程序在完成任务时通过发出嘟嘟声来提醒我 目前 我使用import os然后使用命令行语音程序说 进程完成 我更愿意它是一个简单的 铃 我知道有一个函数可以用于Cocoa apps NSBeep 但我认为这与此没有太
  • Python]将两个文本文件合并为一个(逐行)[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我是蟒蛇新手 我想做的是将文件 a 和文件 b 逐行合并到一个文件中 例如 text file a a n b n c text fi
  • 如何将回溯/sys.exc_info() 值保存在变量中?

    我想将错误名称和回溯详细信息保存到变量中 这是我的尝试 import sys try try print x except Exception ex raise NameError except Exception er print 0 s
  • 检测 IDLE 的存在/如何判断 __file__ 是否未设置

    我有一个脚本需要使用 file 所以我了解到 IDLE 没有设置这个 有没有办法从我的脚本中检测到 IDLE 的存在 if file not in globals file is not set 如果你想做一些特别的事情 file 未设置
  • 缓存 Flask-登录 user_loader

    我有这个 login manager user loader def load user id None return User query get id 在我引入 Flask Principal 之前它运行得很好 identity loa

随机推荐

  • Sql Server处理JSON

    Sql Server 处理 Json 相关技术
  • SQL Server调用WebAPI和WebService

    SQLSERVER调用WebAPI和WebServiceSqlServer调用webapi和webService接口 declare 64 url nvarchar max set 64 url 61 39 http XXX GetToke
  • SQL Server中cross apply和inner join的区别

    Sqlserver 中 CrossApply 和 inner join 的区别 cross apply和inner join有很多相同处 xff0c 都是为了联表查询数据 xff0c 而且取两张表之间的交集 xff0c 不同在于 xff0c
  • C语言 rand函数(随机)

    rand 函数不是真正的随机数生成器 xff0c 而srand 会设置供rand 使用的随机数种子 如果你在第一次调用rand 之前没有调用srand xff0c 那么系统会为你自动调用srand 而使用同种子相同的数调用 rand 会导致
  • 键盘输入 kbhit()

    函数名 xff1a kbhit 功能及返回值 xff1a 检查当前是否有键盘输入 xff0c 若有则返回一个非0值 xff0c 否则返回0 用 法 xff1a int kbhit void 包含头文件 xff1a include lt co
  • 设置光标输出位置

    void gotoXY short x short y 设置光标输出位置 COORD pos 61 x y HANDLE out 61 GetStdHandle STD OUTPUT HANDLE SetConsoleCursorPosit
  • tensorflow错误 Assign requires shapes of both tensors to match. lhs shape= rhs shape=

    在跑tensorflow任务的时候 xff0c 有时候会碰到这种错误 Tensorflow Assign requires shapes of both tensors to match lhs shape 61 20 rhs shape
  • 贪吃蛇游戏源码(可在VC++6.0运行)(在原作者的基础上进行小改进)

    自己做的第一个游戏 xff01 xff01 xff01 说说制作历程吧 xff1a 1 阅读并理解原作者 xff08 没有找到作者名 xff09 源码 2 仿写一边源码 3 经过一天的冥想 xff08 其实是玩了一天吃鸡 xff09 4 然
  • MFC插背景图

    把下面这段代码加进OnPaint 里就行了 CPaintDC dc this CBitmap bitmap bitmap LoadBitmap IDB BITMAP1 这个IDB BITMAP1要自己添加 CBrush brush brus
  • MFC按钮跳转

    需要先添加新建的dialo 的头文件 例如 include 34 AAA h 34 void COnclickDlg OnBnClickedOk AAA Dlg Dlg DoModal
  • MSDN关闭窗口

    退出程序用 AfxGetMainWnd gt SendMessage WM CLOSE 关闭当前窗口 用 DestroyWindow 关闭模式对话框用 EndDialog 0
  • 链表的插入和删除

    while NULL 61 p amp amp i lt pos 1 插入 p 61 p gt pNext 43 43 i if NULL 61 61 p i gt pos 1 return false while NULL 61 p gt
  • 初始化!

    int length list PNODE pHead int len 61 0 需要初始化 xff0c 不然会显示乱码 PNODE p 61 pHead gt pNext while NULL 61 p len 43 43 p 61 p
  • Python爬虫:爬虫所需要的爬虫代理ip是什么?

    当我们对某些网站进行爬去的时候 xff0c 我们经常会换IP来避免爬虫程序被封锁 代理ip地址如何获取 xff1f 其实也是一个比较简单的操作 xff0c 目前网络上有很多IP代理商 xff0c 例如西刺 xff0c 芝麻 xff0c 犀牛
  • MySQL知识点

    主键自增 JDBC中MySQL自增主键的值 xff1a 是通过connection连接发送sql语句时多传入一个参数conn prepareStatement sql PreparedStatement RETURN GENERATED K
  • C语言实现FTP文件传输

    一 要求 FTP实则为两个程序的互相交流 xff0c 把信息指令相互发送并处理 1 客户端请求下载文件 把文件名发送给服务器 2 服务器接收客户端发送的文件名 根据文件名找到文件 xff0c 把文件大小发送给客户端 3 客户端接收到文件大小
  • 我的2013,它不平淡

    2013年春节过后 xff0c 等我再赴学校 xff0c 我已经是大三下学期的学生了 对于一名软件学院的学生 xff0c 这就意味着要整备离开校园出去实习了 果然 xff0c 陆陆续续各大软件公司 xff08 培训部门而已 xff09 或培
  • mac下office文档自动恢复

    如果想要查找mac上自动恢复的文件 xff0c 可以在如下的文件目录中找到 xff0c 注意将 username 替换为自己的用户名 xff1a Excel Users username Library Containers com mic
  • FreeRTOS消息队列/信号量/事件

    1 消息队列主要用于任务之间消息的传递 2 信号量分为计数信号量 二值信号量 互斥信号量 3 事件用于外部事件的触发 4 计数信号量用于发生次数的统计 读取以后可以减1 二值信号量 互斥信号量与二值信号量的主要区别是可以防止优先级翻转 5
  • python装饰器详解-python中的装饰器详解

    在了解装饰器的之前一定要先了解函数作为参数传递 什么是函数内嵌 请参考我之前写的博客函数简介 因为在python里面 函数也是对象 也可以作为参数进行传递 python装饰器本质也是一种特殊函数 它接收的参数是函数对象 然后动态地函数参数添