ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

装饰器

2022-07-21 13:35:18  阅读:150  来源: 互联网

标签:__ f1 wrapper logincheck print 装饰 def


装饰器作用

下面为两个函数增加检查登录功能的代码,方法1需要每个函数下方都添加过于繁琐,方法2调用方式改变,在项目时不希望改变已成功实现的代码(因为可能是借鉴来的不敢修改,不想改变代码的调用方式,
想要解决此类问题可以使用装饰器,装饰器提供了高效,简洁的实现方法

# 方法1 添加检查登录功能
def f1():
    print('check login')
    print('f1',x)

def f2():
    print('check login')
    print('f2')
#调用
f1()
f2()
# 方法2 添加检查登录功能
def logincheck(func):
        print('check login')
        func()

def f1():
    print('f1')

def f2():
    print('f2')
#调用
logincheck(f1)
logincheck(f2)

函数装饰器

# 形成闭包,装饰器
def logincheck(func):
    def wrapper():
        print('check login')
        return func()
    return wrapper

def f1():
    print('f1')

def f2():
    print('f2')
#调用
logincheck = logincheck(f1)
logincheck()


# 使用@
def logincheck(func):
    def wrapper():
        print('check login')
        return func()
    return wrapper
@logincheck
def f1():
    print('f1')
@logincheck
def f2():
    print('f2')
#调用
f1()

#结果一致
check login
f1

@logincheck相当于logincheck = logincheck(f1)作用,logincheck函数返回一个函数,相当于 wrapper = logincheck

调用函数有参数时,装饰器如何改变

def logincheck(func):
    def wrapper(x):
        print('check login')
        return func(x)
    return wrapper
@logincheck
def f1(x):
    print('f1',x)
#调用
f1('python')

#返回值
check login
f1 python

传入多个参数时使用*args(元组),**kwargs(关键字参数)

def logincheck(func):
    def wrapper(*args):
        print('check login')
        return func(*args)
    return wrapper
@logincheck
def f1(x,y):
    print('f1',x,y)
#调用
f1('hello','python')

#返回值
check login
f1 hello python

当传入多个参数时对应改变wrapper内的参数即可

当装饰器存在参数时

def loginname(per):
  def logincheck(func):
      def wrapper():
          print(per,'check login')
          return func()
      return wrapper
  return logincheck
@loginname('x')
def f1()
    print('f1')
f1()
#返回
x check login
f1

@loginname('x') = loginname('x')(f1),先函数loginname('x')返回logincheck,随后调用形式为logincheck(f1)返回wrapper,wrapper=f1,调用f1()=wrapper(),返回结果

_ _name _ _

__name__作用
内置函数,可以观察到模块是自己执行还是被调用

#模块名为nameScript.py
def myFunction():
    print('变量 __name__ 的值是 ' + __name__)
def main():
    myFunction()
if __name__ == '__main__':
    main()
输出:变量 __name__ 的值是 __main__
# 自己直接执行代码时 __name__ 的值是 __main__
# 导入模块
import nameScript as ns
ns.myFunction()
输出:变量 __name__ 的值是 nameScript
# 调用模块时 __name__ 的值是被调用模块的名字
def logincheck(func):
    def wrapper():
        print('check login')
        return func()
    return wrapper
@logincheck
def f1():
    print('f1')
print(f1.__name__)
# 输出wrapper

上述装饰器可以看到f1.__name__的信息被修改为wrapper,我们希望在简介代码的同时不丢失原函数的信息,希望f1.__name__的值为f1,使用functools.wraps来解决这一问题,,wraps本身也是一个装饰器,它能把原函数的元信息拷贝到装饰器里面的 func 函数中,这使得装饰器里面的 func 函数也有和原函数一样的元信息了


from functools import wraps
def logincheck(func):
    @wraps(func) #在与原函数有同样功能的函数前添加
    def wrapper():
        print('check login')
        return func()
    return wrapper
@logincheck
def f1():
    print('f1')
print(f1.__name__)

标签:__,f1,wrapper,logincheck,print,装饰,def
来源: https://www.cnblogs.com/xixis/p/16500282.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有