- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python函数装饰器常见使用方法实例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了Python函数装饰器常见使用方法。分享给大家供大家参考,具体如下:
1、装饰器 。
首先,我们要了解到什么是开放封闭式原则?
软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所以我们应该遵循开放封闭的原则.
也就是说:我们必须找到一种解决方案,能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能.
总结:原则如下:
1、不修改源代码 2、不修改调用方式 。
目的:在遵循1和2原则的基础上扩展新功能.
2、什么是装饰器?
器:指的是工具, 。
装饰:指的是为被装饰对象添加新功能.
完整的含义:装饰器即在不修改装饰对象源代码与调用方式的前提下,为被装饰器对象添加新功能的一种函数,这个函数的特殊之处就在于它的返回值也是一个函数.
一般而言,我们想要拓展原来函数的代码,直接的办法就是侵入代码里面修改,例如:
1
2
3
4
5
6
7
8
|
import
time
def
index():
start_time
=
time.time()
time.sleep(
3
)
print
(
'hello word'
)
stop_time
=
time.time()
print
(
'run time is %s'
%
(stop_time
-
start_time))
index()
|
输出:
hello word run time is 3.000171422958374 。
以上代码就是让你过三秒才打印'hello word',下面我们要再添加一个新功能,和上面的功能一样,但是要传参数进去,过5秒输出结果.
修改1:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
time
def
index():
time.sleep(
3
)
print
(
'hello word'
)
def
home(name):
time.sleep(
5
)
print
(
'welcome %s to home page'
%
name)
def
wrapper(func):
start_time
=
time.time()
func(
'haolo'
)
stop_time
=
time.time()
print
(
'run time is %s'
%
(stop_time
-
start_time))
wrapper(home)
|
输出:
welcome haolo to home page run time is 5.000286102294922 。
这样写感觉还是不怎么好,而且我们还修改了函数的调用方式,很不符合规矩。所以我们还是换一种方式来修改它。通过装饰器的方式.
修改2 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import
time
def
index():
time.sleep(
3
)
print
(
'hello word'
)
def
home(name):
time.sleep(
5
)
print
(
'welcome to %s'
%
name)
def
outter(func):
# func为最原始的inde 和home
def
warpper():
start_time
=
time.time()
func(
'yuan'
)
stop_time
=
time.time()
print
(stop_time
-
start_time)
return
warpper
home
=
outter(home)
###home这个变量名是新赋值的,把原来的home给覆盖了。
home()
|
输出:
welcome to yuan 5.000286102294922 。
这种方式虽然满足了不修改源代码和不修改调用方式的条件,但还是不能够实现两个函数同时运行的功能,说到底还是不行,我们还得想个方式出来。就是让他们两个同时运行。这时,我又想到了上节课所学的知识,就是*args和**kargs,用两个函数通过可变参数形式来实现内嵌函数的形式传入,所以它支持运行是构建参数列表,这对于以上两次不能解决的办法是最有效的。下面我们来试试,看到底能不能成功.
方式3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import
time
def
index():
time.sleep(
3
)
print
(
'hello word'
)
def
home(name):
time.sleep(
5
)
print
(
'welcome %s to home page'
%
name)
def
timmer(func):
#func为最原始的home
def
warpper(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
#调用了最原始的home
stop_time
=
time.time()
print
(stop_time
-
start_time)
return
res
return
warpper
index
=
timmer(index)
#为最新的index = wrapper
home
=
timmer(home)
#为最新的home = wrapper
home(name
=
'yuan'
)
#wrapper=('yuan')
index()
#wrapper
|
输出:
welcome yuan to home page 5.000285863876343 hello word 3.000171661376953 。
看吧,很快就实现了两个功能并用,而且我们还没有修改原始代码,还有调用方式.
其实很简单,我只是用了一个无参装饰器的模板,这个模板可以说是万能的,在以后很多的函数代码都可以用这种方式来套用.
模板:
1
2
3
4
5
|
def
outer(func):
def
inner(
*
args,
*
*
kwargs):
res
=
func(
*
args,
*
*
kwargs)
return
res
return
inner
|
现在又有问题来了,我们调装饰器的时候,每调一次,又要把装饰器对象传进来,调一次又传一次,这样不会觉得很麻烦吗?那么我们又想到了一种方法,就是装饰器语法糖,在被装饰对象的上面加@timmer 用它来取代 index=timmer(index) 。
并且把返回值正常的返回给它.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import
time
def
timmer(func):
#func为最原始的home
def
warpper(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
#调用了最原始的home
stop_time
=
time.time()
print
(stop_time
-
start_time)
return
res
return
warpper
@timmer
#就是取代底下的 index=timmer(index)
def
index():
time.sleep(
3
)
print
(
'hello word'
)
@timmer
#就是取代底下的home=timmer(home) home(name='yuan')
def
home(name):
time.sleep(
5
)
print
(
'welcome %s to home page'
%
name)
index()
home(
'liuyuan'
)
|
输出:
hello word 3.000171661376953 welcome liuyuan to home page 5.000286102294922 。
注意:这里的timmer函数就是最原始的装饰器,它的参数就是一个函数,然后返回值也是一个函数。其中作为参数的这个函数index()和hemo(name)就是在返回函数的wrapper()的内部执行。然后再这两个函数的前面加上@timmer,index()和home(name)函数就相当于被注入了计时功能,现在只需要调用index()和home('yuan'),它就已经变身为'新功能更多的函数了。' 。
所以这里的装饰器就像一个注入的符号:有了它,拓展了原来函数的功能既不需要侵入函数内更改代码,也不需要重复执行原函数.
用装饰器来实现认证功能:
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
|
import
time
current_user
=
{
'username'
:
None
,
#'login_time':None
}
def
auth(func):
# func = index
def
wrapper(
*
args,
*
*
kwargs):
if
current_user[
'username'
]:
print
(
'已经登录过了'
)
res
=
func(
*
args,
*
*
kwargs)
return
res
uname
=
input
(
'输入用户名:'
).strip()
pwd
=
input
(
'密码:'
).strip()
if
uname
=
=
'yuan'
and
pwd
=
=
'123'
:
print
(
'登录成功'
)
current_user[
'username'
]
=
uname
res
=
func(
*
args,
*
*
kwargs)
return
res
else
:
print
(
'用户名或密码错误'
)
return
wrapper
@auth
#index = auth(index)
def
index():
time.sleep(
1
)
print
(
'welcom to index page'
)
@auth
def
home(name):
time.sleep(
2
)
print
(
'welcome %s to home page'
%
name)
input
()
home(
'yuan'
)
|
有参数的装饰器来用于用户认证 。
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
|
import
time
current_user
=
{
'username'
:
None
,
# 'login_time':None
}
def
auth(func):
# func=index
def
wrapper(
*
args,
*
*
kwargs):
if
current_user[
'username'
]:
print
(
'已经登陆过了'
)
res
=
func(
*
args,
*
*
kwargs)
return
res
uname
=
input
(
'用户名>>: '
).strip()
pwd
=
input
(
'密码>>: '
).strip()
if
uname
=
=
'yuan'
and
pwd
=
=
'123'
:
print
(
'登陆成功'
)
current_user[
'username'
]
=
uname
res
=
func(
*
args,
*
*
kwargs)
return
res
else
:
print
(
'用户名或密码错误'
)
return
wrapper
def
timmer(func):
def
wrapper(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
stop_time
=
time.time()
print
(stop_time
-
start_time)
return
res
return
wrapper
@timmer
# timmer 统计的是auth+index的执行时间
@auth
def
index():
time.sleep(
1
)
print
(
'welcome to index page'
)
return
122
index()
|
叠加多个装饰器:
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
|
import
time
current_user
=
{
'username'
:
None
,
# 'login_time':None
}
def
auth(func):
# func=index
def
wrapper(
*
args,
*
*
kwargs):
if
current_user[
'username'
]:
print
(
'已经登陆过了'
)
res
=
func(
*
args,
*
*
kwargs)
return
res
uname
=
input
(
'用户名>>: '
).strip()
pwd
=
input
(
'密码>>: '
).strip()
if
uname
=
=
'egon'
and
pwd
=
=
'123'
:
print
(
'登陆成功'
)
current_user[
'username'
]
=
uname
res
=
func(
*
args,
*
*
kwargs)
return
res
else
:
print
(
'用户名或密码错误'
)
return
wrapper
def
timmer(func):
def
wrapper(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
stop_time
=
time.time()
print
(stop_time
-
start_time)
return
res
return
wrapper
@timmer
# timmer 统计的是auth+index的执行时间
@auth
def
index():
time.sleep(
1
)
print
(
'welcome to index page'
)
return
122
index()
|
希望本文所述对大家Python程序设计有所帮助.
原文链接:https://www.cnblogs.com/lyox/p/8671098.html 。
最后此篇关于Python函数装饰器常见使用方法实例详解的文章就讲到这里了,如果你想了解更多关于Python函数装饰器常见使用方法实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!