简单告诉你啥是python的装饰器

装饰器

定义
装饰器是一个函数,主要用来包装另一个函数或类,加载模块时装饰器已经执行。
装饰器本质上就是一个闭包函数,它可以对已有函数进行额外的功能扩展。
闭包函数有且只有一个参数,必须是函数类型,这样定义的函数才是装饰器。
作用
装饰的目的通常是在不改变原函数名(或类名)的情况下,改变或添加原函数的功能
语法
@装饰器函数名 等价于 函数名 = 装饰器函数名(函数名)
装饰器的执行时间是加载模块时立即执行。
def 装饰器函数名(参数):
		语句块
    return 函数对象

@装饰器函数名
def 函数名(形参列表):
    语句块
1.有参数无返回值
def func(fun):
	def inner(num):
		print("--这是权限验证---")
		fun(num)
	return inner

@func
def test(num):
	print("---这是被装饰函数---")
	print("num is %d" % num)

test(100) 

#--这是权限验证---
#---这是被装饰函数---
#num is 100
2.不定长传参
def func(fun):
	def inner(*args, **kwargs):
		print("--这是权限验证---")
		fun(*args, **kwargs)
	return inner

@func
def test(*args, **kwargs):
	print("---这是被装饰函数---")
	print("*args is ", args)
	print("**kwargs is ", kwargs)

test(100, num=200)
#--这是权限验证---
#---这是被装饰函数---
#*args is  (100,)
#**kwargs is  {'num': 200}
3.带返回值
def func(fun):
	def inner(*args, **kwargs):
		print("--这是权限验证---")
		return fun(*args, **kwargs)
	return inner

@func
def test(num, *args, **kwargs):
	print("---这是被装饰函数---")
  	return "ok"

print(test(100))
#--这是权限验证---
#---这是被装饰函数---
#ok
4.多个装饰器对同一个函数装饰
注:
1.多个装饰器的装饰过程是: 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,
由内到外的装饰过程
2.调用函数时则先执行外部的make_div装饰器 再执行make_p
def make_div(func):
    """对被装饰的函数的返回值 div标签"""
    def inner(*args, **kwargs):
        return "<div>" + func() + "</div>"
    return inner

def make_p(func):
    """对被装饰的函数的返回值 p标签"""
    def inner(*args, **kwargs):
        return "<p>" + func() + "</p>"
    return inner

# 装饰过程: 1 content = make_p(content) 2 content = make_div(content)
# content = make_div(make_p(content))
@make_div
@make_p
def content():
    return "人生苦短"

result = content()
print(result) # <div><p>人生苦短</p></div>
5.带有参数的装饰器
注:
1.装饰器只能有一个参数且是函数名 set_func是装饰器
2.带有参数的装饰器,其实就是定义了一个函数,让函数接收参数,
在函数内部返回的是一个装饰器
## 1.调用set_level并且将1当做实参传递
## 2.用上一步调用的返回值当做装饰器对test1函数进行装饰
def set_level(level_num):
	def set_func(func):
		def call_func(*args, **kwargs):
			if level_num == 1:
				print("--权限验证1--")
			else:
				print("--权限验证2--")
			return func()
		return call_func
	# 将装饰器函数set_func返回
	return set_func

@set_level(1) # 调用set_level(1) = set_func
def test1():
	print("--test1--")

test1()
#--权限验证1--
#--test1--
6.类装饰器
注:
__call__相当于将类的实例对象能直接像函数一样使用
例如:
a = Test()
a() #这是装饰器添加的功能
class Test(object):
  	def __init__(self, func):
		self.func = func
    # 要想类的实例对象能够像函数一样调用,需要在类里面使用call方法,
    # 把类的实例变成可调用对象(callable),也就是说可以像调用函数一样进行调用
    def __call__(self):
      	print("这是装饰器添加的功能")
    	return self.func()    
        
@Test # get_str = Test(get_str)
def get_str():
  	return "haha"
  
print(get_str()) 
# 这是装饰器添加的功能
# haha
7.带参数的类装饰器
class AAA(object):
    def __init__(self, flag):
        self.__flag = flag

    def __call__(self, func):
        def inner(*args, **kwargs):
            if self.__flag == "+":
                print("加法")
            print("课已讲完")
            func(*args, **kwargs)
        return inner

@AAA("+")  # show11 = AAA("+")(show11)
def show11():  # show11 => inner
    print("快要下课啦")

show11()
#加法
#课已讲完
#快要下课啦
8.functools.wraps的用法
# 作用是还原函数名 没有这个now的函数名为wrapper
import functools
def log(func):
  @functools.wraps(func) # 等价于wrapper.__name__ = func.__name__
  def wrapper(*args,**kwargs):
    print("这个函数是 %s"%func.__name__)
    return func(*args,**kwargs)

  return wrapper

@log
def now():
  print("hello")
  return 1

print(now())
print(now.__name__) # wrapper / 加上functools.wraps 为now
# 这个函数是 now
# hello
# 1
# now
9.在类中使用装饰器
class Buy(object):
    def __init__(self):
        self.reset = True  # 定义一个类属性,稍后在装饰器里更改
        self.func = True

        # 在类里定义一个装饰器

    def clothes(func):  # func接收body
        def ware(self, *args, **kwargs):  # self,接收body里的self,也就是类实例
            print('This is a decrator!')
            if self.reset == True:  # 判断类属性
                print('Reset is Ture, change Func..')
                self.func = False  # 修改类属性
            else:
                print('reset is False.')

            return func(self, *args, **kwargs)

        return ware

    @clothes
    def body(self):
        print('The body feels could!')


b = Buy()  # 实例化类
b.body()  # 运行body
print(b.func)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 非常感谢您的提问!以下是我整理的关于浙大版《Python程序设计》的题目集: 第一章 Python初体验 1.1 Python简介及特点 1.2 Python环境搭建 1.3 Python初体验 1.4 Python简单应用:温度转换 第二章 Python基础讲解 2.1 Python基本数据类型 2.2 列表、元组、字典及其操作 2.3 条件语句 2.4 循环语句 2.5 函数 2.6 模块与包 第三章 Python高级语法 3.1 面向对象编程基本概念 3.2 类的定义与使用 3.3 继承与多态 3.4 异常处理机制 3.5 迭代器与生成器 3.6 装饰器 第四章 Python实战 4.1 文件操作 4.2 数据处理与存储 4.3 网络编程 4.4 多线程与多进程 4.5 数据可视化 希望这份题目集对您有所帮助!如果您有任何问题或需要更多帮助,请随时告诉我。 ### 回答2: 浙大版《Python程序设计》题目集是一本用于学习和训练编程技能的教材,主要面向浙江大学的计算机专业学生。这本书包含了丰富多样的编程题目,涵盖了Python编程的各个方面,旨在帮助学生熟悉和掌握Python语言的基础知识和编程能力。 这本书的题目设计紧密结合了计算机科学和软件工程的实际应用场景,题目种类多样,包括数学计算、字符串操作、文件处理、列表和字典操作、图形界面编程等等。每个题目都配有详细的题目描述和要求,让学生能够清楚地理解问题的背景和需求,在解题过程中锻炼问题分析和算法设计的能力。 这本教材还提供了每个题目的解答和思路,供学生参考和学习。同时,书中也介绍了Python的编程技巧和常见的调试技巧,帮助学生提高代码的效率和可维护性。此外,书中还介绍了一些常用的Python库和工具,帮助学生更好地应用Python进行软件开发。 总之,浙大版《Python程序设计》题目集是一本全面而实用的教材,适合计算机专业学生学习和掌握Python编程技能。通过解答其中的题目,学生不仅可以提高编程能力,还可以培养问题分析和算法设计的思维方式,为将来的软件开发和科学研究打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值