python装饰器作用和功能_Python装饰器原理与用法分析

这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下

本文实例讲述了Python装饰器原理与用法。分享给大家供大家参考,具体如下:

1、装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能

2、装饰器的原则:

(1) 装饰器不能修改被装饰的函数的源代码

(2) 装饰器不能修改被装饰的函数的调用方式

3、实现装饰器的知识储备

(1) Python中函数即‘变量'

a、变量在Python中的存储x='Tomwenxing'

y=x

[说明]:

当Python解释器遇到语句x='Tomwenxing'时,它主要完成了两样工作:

1.在内存中开辟了一片空间用来存储字符串‘Tomwenxing'

2.在内存从创建了一个名为x的变量,并用它指向字符串‘Tomwenxing'所占据的内存空间(可以理解为房间和房间号的关系)

cf85b94e9481f92cc7c1600e7dd37506-0.png

而语句y=x意为将变量x对字符串的引用赋值给变量y,即在内存中创建一个变量y,并使其指向变量x所指向的内存空间

cf85b94e9481f92cc7c1600e7dd37506-1.png

b、函数在Python中的存储def test():

pass

[说明]:

在Python中,函数的存储和变量相似,以上面的函数为例,Python解释其主要做两件事:

1.在内存中开辟一个内存空间,用来存储函数代码的字符串(本例中代码只有一句:pass)

2.在内存中创建一个变量test,用来指向存储函数代码字符串的内存空间(相当于test=‘函数体')

cf85b94e9481f92cc7c1600e7dd37506-2.png

因此说在Python中函数即变量

(2) 高阶函数(下面两个条件满足任何一个即为高阶函数)

a、把一个函数名当做实参传递给另外一个函数

[对装饰器的影响]:达到“在不修改被装饰函数源代码的情况下为其添加功能”的效果import time

def bar():

time.sleep(2)

print('in the bar')

def test(func):

start_time=time.time()

func()

stop_time=time.time()

print('函数的运行时间为:',stop_time-start_time)

test(bar)

运行结果:in the bar

函数的运行时间为: 2.0021145343780518

b、返回值中包含函数名

[对装饰器的影响]:达到“不改变函数的调用方式“的效果import time

def bar():

time.sleep(3)

print('in the bar')

def test2(func):

print('新添加的功能')

return func

bar=test2(bar)

bar()

运行结果:新添加的功能

in the bar

(3) 嵌套函数:在一个函数体内用def去声明一个新的函数(不是调用)def foo():

print('in the foo')

def bar(): #声明一个新的函数,而不是调用函数

print('in the bar')

bar()

foo()

运行结果:in the foo

in the bar

4、装饰器的语法:高阶函数+嵌套函数=》装饰器 (下面的例子可以用pycharm的调试器调试一下,看看代码的运行顺序)import time

def timer(func):

def deco(*args,**kwargs):#使用了不定参数

start_time=time.time()

res=func(*args,**kwargs) #运行函数

stop_time=time.time()

print('运行时间:',stop_time-start_time)

return res # 若无返回值,则返回None

return deco

@timer #等价于test1=timer(test1)=deco,即test1()=deco()

def test1():

time.sleep(3)

print('in the test1')

@timer #等价于test2=timer(test2)=deco,即test2(name)=deco(name)

def test2(name):

time.sleep(3)

print('in the test2',name)

test1()

print('-------------分界线------------------------')

test2('Tomwenxing')

运行结果:in the test1

运行时间: 3.0001718997955322

-------------分界线------------------------

in the test2 Tomwenxing

运行时间: 3.000171422958374

5、带参数的装饰器# -*- coding:utf-8 -*-

user,passwd='Tomwenxing','123'

#如装饰器带参数,一般是三层嵌套

def auth(auth_type): #第一层的参数是装饰器的参数

def outer_wrapper(func):#第二层的参数是装饰器要装饰的目标函数

def wrapper(*args,**kwargs):#第三次的参数是目标函数的参数

if auth_type=='local':

username = input('Username:').strip()

password = input('Password:').strip()

if user == username and passwd == password:

print('用户Tomwenxing已经成功登录!')

res = func(*args, **kwargs) #运行目标函数

return res

else:

exit('用户名或密码有错误')

elif auth_type=='ldap':

print('暂不支持这种登录方式!')

return wrapper

return outer_wrapper

def index():

print('欢迎来到index页面')

@auth(auth_type='local') #home=wrapper()

def home(name):

print('%s,欢迎来到home页面' %name)

return 'This is home page'

@auth(auth_type='ldap')

def bbs():

print('欢迎来到bbs页面 ')

index()

print('----------------------分界线-------------------')

print('函数的返回值为:',home('wenxing'))

print('----------------------分界线-------------------')

bbs()

运行结果:欢迎来到index页面

----------------------分界线-------------------

Username:Tomwenxing

Password:123

用户Tomwenxing已经成功登录!

wenxing,欢迎来到home页面

函数的返回值为: This is home page

----------------------分界线-------------------

暂不支持这种登录方式!

相关推荐:

以上就是Python装饰器原理与用法分析的详细内容,更多请关注php中文网其它相关文章!

article_wechat2021.jpg?1111

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java登录界面命令_Java命令行界面(第16部分):JArgp

java登录界面命令这篇文章中介绍的基于Java的命令行参数处理库是IBM developerWorks文章Java编程动态性,第3部分,应用的反射 (第2003 部分,此归档文章于2016年“归档”,但仍可通过PDF下载 )的特色库。 。 该…

tnsnames.ora配置未生效_1分钟了解网络交换机的6种命令配置模式

我们在配置交换机的时候首先要了解的就是交换机命令模式,小编用Cisco思科交换机为例带大家了解交换机的6种配置模式。Cisco IOS提供了用户EXEC模式和特权EXEC模式两种基本的命令执行级别,同时还提供了全局配置、接口配置、Line配置和vlan数据库配置等多种…

java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?

java 线程中创建线程在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet。 java.util.concurrent包甚至没有一个名为ConcurrentHashSet的类,但是从JDK 8开始,您可以使用新添加的keySet(默认值)和ne…

docker 删除所有镜像_关于 Docker 镜像的操作,看完这篇就够啦 !(下)| 文末福利...

紧接着上篇《关于 Docker 镜像的操作,看完这篇就够啦 !(上)》,奉上下篇 !!!镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌握的。本文将带您一步一…

python与access选哪个_从Python连接到Access

I want to be connected to a database Boreas (Access) from Python. How to be connected from Python to Access database Northwind? 解决方案 Here are 2 ways, with COM dispatch and with odbc. You will need the pywin32 extensions and/or pyodbc to use these meth…

设备唯一标识/设备码/设备标识码

文章目录一、MAC地址二、IMEI三、MEIDMEID 和 IMEI 用途的区别四、序列号(一)苹果手机序列号(二)华为手机序列号一、MAC地址 MAC地址(英语:Media Access Control Address),直译为媒…

java登录界面命令_Java命令行界面(第18部分):JCLAP

java登录界面命令Giles Winstanley的JCLAP ( Java命令行参数解析器 )是基于Java的命令行处理库的系列文章中介绍的第18个库。 这篇文章的示例基于JCLAP 1.4 ,它需要Java 8 。 JCLAP主页上指出:“ JCLAP帮助Java开发人员为其应用程…

java登录界面命令_Java命令行界面(第15部分):Jargo

java登录界面命令Jargo在其GitHub主页上定义为“一种减轻程序参数/选项处理的工具”。 当已经存在许多其他命令行处理库时,该页面为另一个命令行处理库提供了基本原理 ,该列表的顶部是“因为类型安全性,不变性和可读性很重要”。 Jargo的选项…

没学过编程能学python吗_我没学过编程,能否学会Python?

学习Python编程语言,是大家走入编程世界的最理想选择。那么我没学过编程,能否学会Python?上海Python培训肯定的回答您:of course!完全能学会!设计大师说过,留白是很好的风景,适当的留白是设计的至高境界;对于没有编程…

java登录界面命令_Java命令行界面(第13部分):JArgs

java登录界面命令JArgs 1.0的区别在于,这是我的第13篇文章的主题,该文章是关于Java命令行参数解析的。 JArgs是一个开放源代码( BSD许可 )库,主要由Steve Purcell和Ewan Mellor等 不同贡献者支持。 事实证明&#xff0…

java登录界面命令_Java命令行界面(第11部分):CmdLn

java登录界面命令这篇文章介绍了如何使用Ostermiller Java Utilities 1.08.02的CmdLn(Java命令行解析器)来处理基于Java的应用程序中的命令行参数。 Ostermiller Java实用程序包括几种不同类型的实用程序 ,但本文的重点是组件页面上描述的“命…

socket模拟http的登陆_Python网络爬虫之模拟登陆 !

为什么要模拟登陆?Python网络爬虫应用十分广泛,但是有些网页需要用户登陆后才能获取到信息,所以我们的爬虫需要模拟用户的登陆行为,在登陆以后保存登陆信息,以便浏览该页面下的其他页面。保存用户信息模拟登陆后有两种…

java登录界面命令_Java命令行界面(第12部分):CLAJR

java登录界面命令第十二篇有关在Java中处理命令行参数的文章的特色库是带有Java Reflection的命令行参数 (CLAJR)。 该“库”是单个Java源文件( CLAJR-0.9.java ), 可从SourceForge下载 。 CLAJR的主页当前显示2006年版…

openssh rpm包_100台CentOS7要升级OpenSSH怎么办?

背景现在有 100 台 Centos7 需要升级 OpenSSH 到 8.3,怎么办呢?一台台的操作显然不符合我摸鱼的风格,既然每台操作都一样,Ansible Roles 就有用武之地了。正常升级流程首先 rpmbuild 打出 OpenSSH 8.3 的 RPM 包,rpm -…

java 从一个容器获取对象,如何从 Spring IoC 容器中获取对象?

前面几篇文章主要分析了 Spring IoC 容器如何初始化,以及解析和注册我们定义的 bean 信息。其中,「Spring 中的 IoC 容器」对 Spring 中的容器做了一个概述,「Spring IoC 容器初始化」和「Spring IoC 容器初始化(2)」分析了 Spring 如何初始化…

thymeleaf与jsp_PagingAndSortingRepository –如何与Thymeleaf一起使用

thymeleaf与jsp在本教程中,我将演示如何通过分页显示Thymeleaf中的企业客户列表。 1 –项目结构 我们有一个正常的Maven项目结构。 2 –项目依赖性 除了正常的Spring依赖关系之外,我们还添加Thymeleaf和hsqldb,因为我们使用的是嵌入式数据…

MySQL 批量生成 SQL 脚本语句解决实际的业务需求/如何拼接字符串/拼接字符串的 SQL 语句

文章目录实际需求分析思路写拼接 SQL 脚本的脚本语句执行得到脚本语句保存成 SQL 脚本文件实际需求 有些行政区域的字段 area_fullname 是空的,如何补全呢?如下所示: 分析思路 (一)如何取到每个区域的上级名称和上…

php的变量都放在哪里,php变量一般放在哪个位置

php变量一般放在哪个位置php定义变量的要求格式,是非常宽松的,至于在哪里定义变量就需要看你的需求,可以在构造函数,也可以在你定义的方法中定义局部变量,也可以在构造函数外面定义全局变量。// 局部变量 函数内部func…

oauth2令牌刷新_了解OAuth2令牌认证

oauth2令牌刷新1.简介 在本教程中,我们将了解OAuth2令牌身份验证 ,以便只有经过身份验证的用户和应用程序才能获得有效的访问令牌,该令牌随后可用于访问服务器上的授权API(在OAuth术语中仅是受保护的资源)。 使用基于…

jsap支付_Java命令行界面(第20部分):JSAP

jsap支付JSAP ( Java Simple Argument Parser )2.1是本系列文章的第二十篇,重点是处理Java的命令行参数。 JSAP页面描述了该库存在的原因:“我在Internet上找到了多个解析器,所有解析器都处理了开关,但是没…