python装饰器传递参数_python装饰器的参数传递

被装饰器装饰的函数名即使没有被调用(因为有@xxx,会触发运行装饰器),(装饰器工厂函数)定义装饰器的代码已经运行了(最内部的那个函数并没有运行)(把被装饰的原函数引用赋值给了装饰器内部的那个函数名),当下边通过该函数名调用时,会调用到装饰器内部的那个函数()

装饰器:在不修改函数源代码的基础上,添加函数功能

一个简单的装饰器

def log_time(func): # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用

def make_decorater():

print('现在开始装饰')

func()

print('现在结束装饰')

return make_decorater # log_time()被调用后,运行此函数返回make_decorater()函数的引用make_decorater

@log_time # 此行代码等同于,test=log_time(test)=make_decorater

def test():

print('我是被装饰的函数')

test() # test()=make_decorater()

D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py

现在开始装饰

我是被装饰的函数

现在结束装饰

Process finished with exit code 0

当被装饰的函数有形参时

def log_time(func):

def make_decorater(*args,**kwargs): # 接受调用语句的实参,在下面传递给被装饰函数(原函数)

print('现在开始装饰')

test_func = func(*args,**kwargs) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回

print('现在结束装饰')

return test_func # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。

return make_decorater

@log_time

def test(num):

print('我是被装饰的函数')

return num+1

a = test(2) # test(2)=make_decorater(2)

print(a)

D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py

现在开始装饰

我是被装饰的函数

现在结束装饰

3

Process finished with exit code 0

当@装饰器后有参数时

def get_parameter(*args,**kwargs): # 工厂函数,用来接受@get_parameter('index.html/')的'index.html/'

def log_time(func):

def make_decorater():

print(args,kwargs)

print('现在开始装饰')

func()

print('现在结束装饰')

return make_decorater

return log_time

@get_parameter('index.html/')

def test():

print('我是被装饰的函数')

# return num+1

test() # test()=make_decorater()

D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py

('index.html/',) {}

现在开始装饰

我是被装饰的函数

现在结束装饰

Process finished with exit code 0

两个装饰器同时修饰一个函数(重点看执行顺序)

def log_time1(func):

def make_decorater(*args,**kwargs):

print('1现在开始装饰')

test_func = func(*args,**kwargs)

print('1现在结束装饰')

return test_func

return make_decorater

def log_time2(func):

def make_decorater(*args,**kwargs): # 接受调用语句的实参,在下面传递给被装饰函数(原函数)

print('2现在开始装饰')

test_func = func(*args,**kwargs) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回

print('2现在结束装饰')

return test_func # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。

return make_decorater

@log_time1

@log_time2

def test(num):

print('我是被装饰的函数')

return num+1

a = test(2) # test(2)=make_decorater(2)

print(a)

D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py

1现在开始装饰

2现在开始装饰

我是被装饰的函数

2现在结束装饰

1现在结束装饰

3

Process finished with exit code 0

注意看执行结果(print,只有执行就会输出到屏幕)(return将数据返回给接受的变量或引用)

def makeBold(fn):

def wrapped1():

print('1')

b = "" + fn() + "" # 此行fn()调用了wrapped(),所以wrapped()执行了print输出到屏幕,然后fn()接受到了wrapped() return返回的结果"" + fn() + "",所以需要等待wrapped()

print('1end') # 只有b = "" + fn() + ""执行完毕才会执行这一行,只有wrapped()函数 return返回后,上一行代码才执行

return b

return wrapped1

def makeItalic(fn):

def wrapped():

print('2')

a = return "" + fn() + "" # 此行fn()调用了test3(),所以test3()执行了,然后fn()接受到了test3()中returnd返回的结果"hello world-3",所以需要等待test3

print('2end') # 当test3()返回后,上一行代码执行完毕,在屏幕上输出此行

return a

return wrapped

@makeBold

@makeItalic

def test3():

return "hello world-3" # return 给了wrapped,wrapped又return给了wrapped;

a = test3() # 此行test3() = wrapped1(),test3()调用了函数所以装饰器才执行。a接受了装饰器return的结果

print(a)

D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/text.py

1

2

2end

1end

hello world-3

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值