python之装饰器(decorator)

 

python的装饰器如果用得好,那是大神,用的不好最好别用。。。

 

装饰器(decorator)主要包含俩大属性:

1、不能改变原有函数的调用方式

2、不能改变原有函数的代码

 

第一个表示,我不需要改变原来代码的结构

第二个表示,我也不需要改吗原有函数的代码,特别是一些核心代码

 

先写个简单的装饰器:

def printFuncName(func):
    def wrapper():
        print("Enter func " + func.__name__)
        func()
    return wrapper

@printFuncName
def helloWorld():
    print("This is first helloworld!")

helloWorld()

  

如上,printFuncName是个装饰器,打印进入函数的名称,helloworld是一个简单函数

如果没有装饰器printFuncName,函数helloworld调用方式为:helloworld()

加了装饰器之后(@printFuncName),调用方式仍然为helloworld(),而且也非常简洁

其实在加了装饰器之后,原始调用方式应该是下面这样:

def printFuncName(func):
    def wrapper():
        print("Enter func " + func.__name__)
        func()
    return wrapper

def helloWorld():
    print("This is first helloworld!")

helloWorld = printFuncName(helloWorld)
helloWorld()

而为了写得简洁,所以helloWorld = printFuncName(helloWorld)直接用@printFuncName来代替了

 

说到这儿必须说如果原函数带参数怎么办?

这里可以把参数写到wrapper里面,如下所示:

def printFuncName(func):
    def wrapper(x):
        print("Enter func " + func.__name__)
        func(x)
    return wrapper

@printFuncName
def helloWorld(x):
    print("This is first helloworld!")
    print(x*2)

helloWorld(3)

 

当然有人想到,每个函数参数并不是相同的,怎么做?

python中有可变参数*args和**kwargs,这样不管你有多少个参数都可以搞定,如下:

def printFuncName(func):
    def wrapper(*args,**kwargs):
        print("Enter func " + func.__name__)
        func(*args)
    return wrapper

@printFuncName
def helloWorld(x):
    print("This is first helloworld!")
    print(x*2)

@printFuncName
def sampleTest(x,y):
    print("This is sampleTest func!")
    print(x**y)

helloWorld(3)
sampleTest(3,3)

 

是不是很简单?但实际应用中怎么去用,是很关键的,只有多用多总结才能用得好~~

 

posted @ 2018-08-04 16:51  水里的芋头  阅读(290)  评论(0编辑  收藏  举报