魔术方法__call__

__call__ 是一个特殊方法(也称为魔术方法),用于使一个类的实例能够像函数一样被调用。当定义了这个方法后,实例对象可以后接括号(即 ())来触发调用,这会让实例表现得像函数一样。

  1. 使实例可调用​:允许类的实例像函数一样被调用。
  2. 保持状态​:可以在多次调用之间保持实例的状态(因为实例可以存储属性)。
  3. 实现装饰器​:常用于实现装饰器类(Decorator Class)。
  4. 模拟函数行为​:让对象具备函数的行为,同时保留类的特性(如属性、方法)。

基本语法

class MyClass:def __call__(self, *args, **kwargs):# 定义调用时的行为return "Called with:", args, kwargsobj = MyClass()
result = obj(1, 2, 3, name="Alice")  # 触发 __call__
# result = obj()  # 触发 __call__
print(result)# ('Called with:', (1, 2, 3), {'name': 'Alice'})
# ('Called with:', (), {})

输出:​

('Called with:', (1, 2, 3), {'name': 'Alice'})

关键特点

  1. ​***args 和 **kwargs**​
    __call__ 可以接受任意数量的位置参数和关键字参数,类似于普通函数。

  2. 实例本身仍然是一个对象
    即使定义了 __call__,实例仍然可以拥有属性和方法:

    class Adder:def __init__(self, initial=0):self.total = initialdef __call__(self, x):self.total += xreturn self.totaladd = Adder(10)
    print(add(5))  # 15(10 + 5)
    print(add(3))  # 18(15 + 3)
  3. 用于装饰器
    __call__ 可以让类的实例作为装饰器使用:

    class Logger:def __init__(self, func):self.func = funcdef __call__(self, *args, ​**kwargs):print(f"Calling {self.func.__name__}")return self.func(*args, ​**kwargs)@Logger
    def greet(name):return f"Hello, {name}!"print(greet("Alice"))

    输出:​

    Calling greet
    Hello, Alice!

​**__call__ vs __init__**​

方法调用时机用途
__init__实例化时调用(obj = MyClass()初始化对象属性
__call__实例被调用时(obj()让实例像函数一样执行

实际应用场景

  1. 状态保持的函数​(类似闭包)

    class Counter:def __init__(self):self.count = 0def __call__(self):self.count += 1return self.countcounter = Counter()
    print(counter())  # 1
    print(counter())  # 2
  2. 实现策略模式

    class Multiply:def __call__(self, a, b):return a * bclass Add:def __call__(self, a, b):return a + bdef calculate(operation, a, b):return operation(a, b)print(calculate(Multiply(), 3, 4))  # 12
    print(calculate(Add(), 3, 4))      # 7
  3. 动态生成对象行为

    class Power:def __init__(self, exponent):self.exponent = exponentdef __call__(self, x):return x ​**​ self.exponentsquare = Power(2)
    cube = Power(3)
    print(square(4))  # 16
    print(cube(3))    # 27

总结

  • __call__ 让类的实例可以像函数一样被调用。
  • 适用于需要保持状态的函数、装饰器类、策略模式等场景。
  • 不同于 __init__,它控制的是实例的调用行为,而非初始化行为。

如果你想让一个对象既能存储数据又能像函数一样执行操作,__call__ 是一个非常有用的工具!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912863.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP中的异常处理与错误日志记录

在PHP编程实践中,异常处理是一项至关重要的技能,它能够帮助开发者识别和响应程序执行过程中发生的非预期事件。与此同时,错误日志记录是确保应用程序可靠性和稳定性的关键组成部分。本文将详细介绍如何在PHP中实现这两个方面的技术。 首先&a…

JS去除空格(数组内字符串)

1.JS中去除空格 去除这个数组中每个对象内部参数(也就是属性值)的空格,可以通过遍历数组,再遍历每个对象的属性,使用 trim() 方法来去除字符串首尾的空格。以下是具体实现代码: let data [{ designHours:…

【Spring篇01】:Bean的线程安全问题总结

文章目录 1. 核心问题:Spring 框架中的 Bean 是线程安全的吗?2. 最佳实践与解决方案禁止方案:滥用prototype作用域推荐方案(按优先级排序) 3. 生产环境中的典型案例Case 1:订单服务统计Case 2:用…

本地项目上传git

将您本地的项目代码上传到一个私有的、别人看不见的 GitHub 仓库,是进行云端协作(如使用 Google Colab)、版本控制和代码备份的最佳实践。这是一个非常重要的技能。 整个过程可以分为三个部分: 准备工作:在您的电脑上…

【.NET Framework 窗体应用程序项目结构介绍】

在使用 Visual Studio (VS) 开发 .NET Framework 窗体应用程序(Windows Forms App) 时,项目结构通常包含以下核心文件夹和文件。以下是详细介绍: 1. 项目根目录下的主要文件 (1) .csproj 文件 作用:C# 项目文件&…

【SpringAI】4.多模态提问

SpringAI多模态提问 概述 SpringAI支持多模态输入,允许AI模型同时处理文本和图像内容。这对于需要视觉理解的AI应用场景非常有用,如图像描述、视觉问答、图像分析等。 核心概念 1. Media类 SpringAI使用Media类来表示多模态内容,支持图…

自动化提示工程:未来AI优化的关键突破

自动化提示工程:未来AI优化的关键突破 自动化提示工程能够自动化或半自动化地生成或优化提示词,以探索大规模的提示词组合,并通过 自动优化技术提升提示词生成的稳定性。 依据自动化提示工程实现形式在逻辑推理和效能导向 两个维度的取舍上,将其分为基于思维链的自动化提示工…

多模态大语言模型arxiv论文略读(148)

A Comprehensive Survey and Guide to Multimodal Large Language Models in Vision-Language Tasks ➡️ 论文标题:A Comprehensive Survey and Guide to Multimodal Large Language Models in Vision-Language Tasks ➡️ 论文作者:Chia Xin Liang, P…

关于.net core开发的实体所有注解详解

以下是对 .NET Core 开发中实体类(用于数据模型)和 Web API 控制器/方法(用于定义接口)常用注解属性(Attributes)的详细说明与示例,涵盖数据验证、API 行为控制、序列化、Swagger/OpenAPI 文档生…

【安全工具】SQLMap 使用详解:从基础到高级技巧

目录 简介 一、安装与基础配置 1. 安装方法 2. 基本语法 二、基础扫描技术 1. 简单检测 2. 指定参数扫描 3. 批量扫描 三、信息收集 1. 获取数据库信息 2. 获取当前数据库 3. 获取数据库用户 4. 获取数据库版本 四、数据提取技术 1. 列出所有表 2. 提取表数据 …

Redis大Key拆分实战指南:从问题定位到落地优化

引言 最近在项目里遇到一个棘手问题:生产环境的Redis突然变“卡”了!查询延迟从几毫秒飙升到几百毫秒,监控面板显示某个节点CPU使用率飙到90%。排查半天才发现,原来是某个用户订单的Hash Key太大了——单Key存了100多万个订单字段…

RabbitMQ简单消息发送

RabbitMQ简单消息发送 简单代码实现RabbitMQ消息发送 需要的依赖 <!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId><version>x.x.x</version>&l…

【阅读笔记】基于双边滤波改进的空域滤波算法

一、双边滤波空域滤波算法 双边滤波是一种典型的非线性滤波算法。基于高斯滤波&#xff0c;双边滤波利用强度的变化来保存边缘信息&#xff0c;解决了边缘模糊在视觉观感上认为重要信息丢失的问题。双边滤波的滤波效果主要取决于两个参数&#xff1a;两个像素的空间邻近性和灰…

华为交换机堆叠与集群技术深度解析附带脚本

一、引言 在企业园区网、数据中心等网络场景中&#xff0c;为了提升网络的可靠性、扩展性和管理效率&#xff0c;华为交换机提供了堆叠&#xff08;Stack&#xff09;和集群&#xff08;CSS&#xff0c;Cluster Switch System &#xff09;技术。这两种技术能够将多台物理交换…

Python网络爬虫(十三)- 数据解析模块 BeautifulSoup

1、BS4简介 BeautifulSoup(简称 BS4) 是一个用于解析 HTML 和 XML 文档的 Python 第三方库。它能够从网页或其他 HTML/XML 格式的文本中提取数据,并将其转换为结构化的对象,方便开发者快速定位、提取和操作所需信息。它的核心功能是通过解析器将无序的标记语言转换为树形结…

如何使用 Pytorch Lightning 启用早停机制

【PL 基础】如何启用早停机制 摘要1. on_train_batch_start()2. EarlyStopping Callback 摘要 本文介绍了两种在 PyTorch Lightning 中实现早停机制的方法。第一种是通过重写on_train_batch_start()方法手动控制训练流程&#xff1b;第二种是使用内置的EarlyStopping回调&#…

深入理解前缀和与差分算法及其C++实现

前缀和与差分是算法竞赛和编程中非常重要的两种技巧&#xff0c;它们能够高效地处理区间查询和区间更新问题。本文将详细介绍这两种算法的原理、应用场景以及C实现。 一、前缀和算法 1.1 前缀和的基本概念 前缀和&#xff08;Prefix Sum&#xff09;是一种预处理技术&#x…

HugeGraph【部署】Linux单机部署

注: hugegraph从版本 1.5.0 开始&#xff0c;需要 Java11 运行时环境 一、安装JDK11 1.下载JDK11 https://www.oracle.com/java/technologies/downloads/#java11 2.解压缩包 tar -zxvf jdk-11.0.27_linux-x64_bin.tar.gz 3.修改/etc/profile环境变量 export JAVA_HOME/usr…

C++异步编程里避免超时机制

C标准库中时钟&#xff08;Clock&#xff09; 这段内容主要介绍了C标准库中**时钟&#xff08;Clock&#xff09;**的概念和分类&#xff0c;以及它们在时间测量中的作用。以下是关键信息的解读&#xff1a; 一、时钟的核心特性 C中的时钟是一个类&#xff0c;提供以下四个基…

npm install安装不成功(node:32388)怎么解决?

如果在执行 npm install 时出现问题&#xff0c;尤其是 node:32388 相关的错误&#xff0c;这通常意味着某些依赖或配置出了问题。这里有一些常见的解决方法&#xff0c;你可以尝试&#xff1a; 1. 清除 npm 缓存 有时候&#xff0c;npm 缓存问题会导致安装失败。你可以清除 …