欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Python之__call__ 函数和装饰器的作用

Python之__call__ 函数和装饰器的作用

2024/10/24 15:12:53 来源:https://blog.csdn.net/xp_fangfei/article/details/140343762  浏览:    关键词:Python之__call__ 函数和装饰器的作用

文章目录

    • 前言
    • __call__ 函数
      • 代码介绍
    • Python装饰器
      • 函数装饰器
      • 带参数的函数装饰器
      • 装饰器运用场景

前言

  在Python代码中,定义类的时候经常会用到__call__()方法,具体有什么含义呢?;除了__call__()方法。python装饰器也经常被用到;接下来我们就聊一聊__call__()方法;和装饰器是如何实现的。

在这里插入图片描述
温故而知新,往期经典回顾:Python之numpy常用知识点总结

call 函数

  在Python中__call__ ()方法是一个特殊方法(也称为魔术方法或双下方法),它允许类的实例像函数那样被调用。当你尝试对一个对象使用圆括号()进行“调用”时,Python解释器会自动在该对象上查找__call__ ()方法,并调用它(如果存在);

代码介绍

  如何更直观的正确的理解上面的那句话呢,下面我们通过一个简单的程序来解释一下,下面这个程序就是正常的python类。里面有一个初始化代码,还有一个名字叫**test()**的函数;我们先实例化Adder类,再调用实例化的对象add() 发现,程序报错不能调用;

class Adder:def __init__(self, number):self.number = numberdef test(self, other):return self.number + otheradd = Adder(5)
b = add(6)
print(b)     

结果:程序报错不能调用add 对象;

File "D:\Study\ml_practice\py\PyTorch_YOLOv1\test_xp.py", line 17, in <module>b = add(6)
TypeError: 'Adder' object is not callable

  如果我们在这个类中添加一个__call__ ()方法,会发生什么情况呢?

class Adder:def __init__(self, number):self.number = numberdef __call__(self, other):return self.number + otheradd = Adder(5)
b = add(6)  # 对象add可以像函数一样调用(这就是__call__ ()函数的作用)
print(b)   # 

结果:

输出:11

从上述代码可以看出实例化的对象add() 可以正常调用了,这是因为我们在类Adder中声明了__call__()方法,它允许类的实例像函数那样被调用;通过上面的的例子就可以很清楚的知道__call__()的作用了;

Python装饰器

  Python装饰器是一种语法糖,用于在不改变原有函数代码的情况下,为函数添加额外的功能。
  装饰器本质上是一个函数,它接收一个函数作为参数,并返回一个新的函数,通常使用@语法糖来应用装饰器。

函数装饰器

  函数装饰器是最常见的装饰器形式,它接收一个函数并返回一个新的函数。这里有一个简单的例子:

def my_decorator(func):  def wrapper():  print("Something is happening before the function is called.")  func()  print("Something is happening after the function is called.")  return wrapper  @my_decorator  
def say_hello():  print("Hello!")  say_hello()  

输出:

Something is happening before the function is called.  
Hello!  
Something is happening after the function is called.

  在这个例子中,my_decorator是一个装饰器,它接收say_hello函数作为参数,并返回一个新的函数wrapper。当调用say_hello()时,实际上调用的是wrapper()函数,该函数在调用原始say_hello函数之前和之后添加了额外的打印语句。

带参数的函数装饰器

  如果你的函数需要参数,装饰器需要稍作修改以接受这些参数。

def my_decorator(func):  def wrapper(*args, **kwargs):  print("Something is happening before the function is called.")  func(*args, **kwargs)  print("Something is happening after the function is called.")  return wrapper  @my_decorator  
def greet(name):  print(f"Hello, {name}!")  @my_decorator
def add(a,b):print(2*a+b)greet("Alice")
add(3,8)

结果:

#greet("Alice")结果
Before the function is called.
Hello,Alice
After the function is called.#add(3,8)结果
Before the function is called.
14
After the function is called.

  在这个例子中,wrapper函数使用了*args和**kwargs来允许接收任意数量和类型的参数,并将它们传递给被装饰的函数func。

装饰器运用场景

装饰器的应用非常广泛,可以用于实现各种功能,例如:

  • 记录函数执行时间:通过在装饰器函数中记录函数执行的开始和结束时间,可以计算函数的执行时间。
  • 缓存函数结果:通过在装饰器函数中维护一个缓存,可以避免重复计算相同参数的函数结果,提高函数的执行效率。
  • 实现权限控制:通过在装饰器函数中检查用户的权限,可以控制用户对某些函数的访问权限。
  • 日志记录:通过在装饰器函数中记录函数的输入参数和返回值,可以方便地进行调试和错误排除。
  • 错误处理:通过在装饰器函数中捕获异常并进行处理,可以避免函数抛出异常导致程序崩溃。

Python装饰器是一种非常强大的语法糖,可以帮助我们实现各种功能,提高代码的复用性和可维护性。

案例实现:打印函数执行时间消耗

import time
# 注意:这个是带参数的装饰器
def calculate_execution_time(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()execution_time = end_time - start_timeprint(f"函数 {func.__name__} 的执行时间为: {execution_time:.2f} 秒")return resultreturn wrapper@calculate_execution_time
def my_function(a, b):# 假设这里是一个耗时的操作time.sleep(1)# 被装饰函数本身的功能return a+bsum = my_function(1, 2)
print(sum)

结果:

函数 my_function 的执行时间为: 1.01sum:3

好啦,今天就分享到这里吧!关注我持续更新有价值的内容!
如有错误欢迎指正,如果帮到您请点赞加收藏哦!

以上程序可以关注我的微信公众号:回复"深度学习资料"领取深度学习相关资料(100本人工智能书籍),实时更新深度学习相关知识!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com