python中魔术方法__str__与__repr__的区别

在这里插入图片描述

在Python中,__str____repr__是两个常见的魔法方法(也称为双下方法或dunder方法),它们用于定义对象的字符串表示形式。它们的主要区别在于它们的用途和使用场景。

__str__

  • 用途__str__方法用于为用户提供一个易读的字符串表示形式。当使用str()函数或print()函数打印对象时,会调用该方法。

  • 目标用户:面向最终用户,旨在提供一个易读且有意义的描述。

  • 示例

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return f"Person(name={self.name}, age={self.age})"
    
    p = Person("Alice", 30)
    print(p)  # 输出:Person(name=Alice, age=30)
    

__repr__

  • 用途__repr__方法用于为开发者提供一个更正式的字符串表示形式,通常应尽可能地提供一个准确且完整的描述。当使用repr()函数或在交互式解释器中直接输入对象时,会调用该方法。

  • 目标用户:面向开发者,旨在提供一个详细且准确的描述,通常应该包含足够的信息以便于通过该字符串重新创建对象。

  • 示例

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __repr__(self):
            return f"Person(name={self.name!r}, age={self.age!r})"
    
    p = Person("Alice", 30)
    print(repr(p))  # 输出:Person(name='Alice', age=30)
    

综合示例

如果一个类同时定义了__str____repr__,它们会分别在不同的上下文中被调用:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"Person(name={self.name}, age={self.age})"

    def __repr__(self):
        return f"Person(name={self.name!r}, age={self.age!r})"

p = Person("Alice", 30)

# 使用 str() 或 print() 函数时调用 __str__
print(str(p))  # 输出:Person(name=Alice, age=30)
print(p)       # 输出:Person(name=Alice, age=30)

# 使用 repr() 或在交互式解释器中直接输入对象时调用 __repr__
print(repr(p)) # 输出:Person(name='Alice', age=30)

总结

  • __str__:提供面向用户的友好字符串表示。
  • __repr__:提供面向开发者的正式且完整的字符串表示,通常应该包括可以重新创建对象的信息。

_repr__方法的设计理念

在Python中,__repr__方法的设计理念之一是提供一个准确且完整的字符串表示形式,使得该字符串表示形式尽可能地能够重新创建该对象。这意味着理想情况下,使用eval()函数可以通过该字符串表示形式重新生成一个相同的对象实例。

为什么需要这种设计?

  1. 调试和开发:在调试和开发过程中,开发者希望通过查看对象的__repr__输出来获取尽可能多的信息,以便理解对象的当前状态。
  2. 日志记录:在记录日志时,使用__repr__可以确保记录的信息详尽且准确,有助于在日后分析和调试。
  3. 对象重建:虽然在实际应用中不总是使用eval()来重建对象,但这种设计理念保证了__repr__输出尽可能地完整和精确。

示例说明

以下是一个类及其__repr__实现的示例,该实现能够提供重新创建对象的信息:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person(name={self.name!r}, age={self.age!r})"

p = Person("Alice", 30)
print(repr(p))  # 输出:Person(name='Alice', age=30)

# 使用 eval() 来重新创建对象
p_copy = eval(repr(p))
print(p_copy)   # 输出:Person(name='Alice', age=30)
print(p == p_copy)  # 输出:False (因为它们是两个不同的对象实例)
print(p.name == p_copy.name and p.age == p_copy.age)  # 输出:True (因为它们的属性值相同)
  • __repr__方法返回了一个字符串,这个字符串看起来像一个调用类构造函数的表达式,并且包含了创建该对象所需的所有信息。
  • 通过eval(repr(p))可以重新创建一个具有相同属性的新对象p_copy

注意事项

  • 安全性:在实际开发中,应谨慎使用eval()函数,因为它会执行传入的字符串,这可能带来安全风险。如果字符串包含恶意代码,可能会导致不可预期的后果。
  • 复杂对象:对于一些复杂对象(如涉及外部资源、网络连接、文件句柄等),__repr__可能无法完全捕捉所有信息。在这种情况下,__repr__应尽量提供尽可能多的有用信息,同时注意避免安全和隐私问题。

总结

__repr__方法旨在提供一个正式且详细的对象表示形式,使开发者能够通过该表示形式了解对象的内部状态,并在理想情况下能够重新创建该对象。这种设计理念在调试、日志记录和对象序列化等场景中尤为有用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【嵌入式DIY实例】-Nokia 5110显示DHT11/DHT22传感器数据

Nokia 5110显示DHT11/DHT22传感器数据 文章目录 Nokia 5110显示DHT11/DHT22传感器数据1、硬件准备2、代码实现2.1 显示DHT11数据2.2 显示DHT22数据本文介绍如何将 ESP8266 NodeMCU 开发板 (ESP-12E) 与 DHT11 数字湿度和温度传感器以及诺基亚 5110 LCD 连接。 NodeMCU 从 DHT11…

.NET Core 服务注册步骤总结

总结一下 .NET Core 服务注册的步骤: .NET Core Web Api 项目服务注册步骤: 创建一个接口,和实现类 比如:IMyService, CnService 在 Program.cs 的 var app builder.Build(); 语句之前加上: var builder WebApplic…

【面经总结】 Java基础 - 异常

异常 介绍一下 Java 的异常体系 Java 的异常体系是由 Throwable 类及其子类构成的。 Throwable 包含两个子类:Error(错误)和 Exception(异常) Error 表示错误,通常不需要程序员处理,如内存溢…

python中的turtle

turtle个别指令 初始箭头默认指向为东(右) 往前(右)三个格:turtle.forward(3) 往后(左)三个格:turtle.backward(3) 往左转90度:turtle.left(90) 往右转90度&#xf…

Attention与轻量级ResNet融合,低资源消耗下实现效率和性能完美平衡

注意力机制通过让模型关注图像关键区域提升了识别精度,而轻量级残差网络通过减少参数和计算量,实现了在低资源消耗下的优秀性能。 结合注意力机制与轻量级残差网络,既能让模型能够更高效地关注输入数据中的关键信息,提升模型处理…

vs调试时无法找到文件-chromium源码编译

一直跟着教程走结果报错了,找了半天的教程无法解决,于是乎只好重来,因为这个是属于项目调试,报错了可以重新编译项目就好。在重新做的过程中发现路径写错了

人工智能的等价形式

经典的人工智能,采用“梯度下降法”,运算量很大,约是esp2。其中e是epoch,训练的周期数;s是sample,训练样本的数量;p是parameter,参数的数量。 人工智能有等价形式,它不需…

DPI简析

DPI简析 一、DPI与PPI二、硬件设备的DPI2.1打印机DPI2.2显示器DPI2.2.1显示器DPI计算2.2.2显示器分辨率与系统分辨率2.2.3常见分辨率 2.3鼠标DPI 三、图片DPI3.1图片DPI与打印尺寸3.1.1图片打印尺寸计算3.1.2常用的照片尺寸及DPI 3.2图片DPI与屏幕显示3.3修改图片DPI 参考文档 …

Windos10上Podman安装运行mysql8

记录以下在windows10系统上Podman v5.1.1安装MySQL8全过程。 目录 一、拉取mysql8镜像二、创建宿主目录三、创建 my.cnf文件四、创建Mysql8容器五、windows上Podman安装运行mysql8失败问题描述 解决办法① 通过PowerShell进入wsl② 修改wsl系统配置③ 重启wsl,Podma…

3个月搞定计算机二级C语言!高效刷题系列进行中

文章目录 前言备考计算机二级C语言为什么考二级C语言?刷题总结后发布系列文章后记免责声明 前言 大家好,我是梁国庆。 计算机二级应该是每一位大学生的必修课,相信很多同学的大学flag中都会有它的身影。 我在大学里也不止一次的想要考计算…

【运维知识大神篇】运维界的超神器Kubernetes教程14(RBAC三种认证方式详解:基于用户+基于用户组+基于服务账号)

本篇文章继续给大家介绍Kubernetes,内容依旧烧脑,不过内容也已经过了一大半了,如果你把我Kubernetes前面的教程都看懂了的话,那么你已经很厉害了,坚持下去!本篇文章主要介绍RBAC的三种认证方式,…

Python使用tkinter库设置背景图片、label显示位置和label设置显示图片

tkinter 设置背景图片 label显示位置 label设置显示图片 from tkinter import * import tkinter as tk from PIL import ImageTk from PIL import Imagedef get_img(filename, width, height):im Image.open(filename).resize((width, height))im ImageTk.PhotoImage(im)…

Java的集合框架总结

Map接口和Collection接口是所有集合框架的父接口: Collection接口的子接口包括:Set接口和List接口 Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等 Set接口的实现类主要有:HashSet、Tr…

【CH32V305FBP6】USBD HS 描述符修改

文章目录 前言设备描述符完整描述符配置描述符CDC 描述符接口关联描述符接口描述符功能描述符端点描述符接口描述符端点描述符 HID 描述符接口描述符 新增一个 HID 设备 前言 USB HS 复合设备,CDCHID 功能:串口、DAP、CAN-HID、RS485 设备描述符 htt…

远程抄表系统方案

一、远程抄表系统简述 远程抄表系统,是一种智能化的自动化数据收集技术性,主要运用于电力工程、供水公司、天然气等公共服务行业,完成对消费者表计数据的远程、即时、智能采集。这类系统不但降低了成本,降低了人力抄表错误&#…

手部出现这4种症状,可能是糖尿病先兆!务必及时监测血糖

糖尿病来袭,手部或先知!出现这 4 种症状,务必尽快监测血糖 第一,手指麻木感明显,当持续性的高血糖损害手部血管与神经末梢时,便会导致手指产生麻木以及刺痛之感。而且随着血糖不断升高,受损的血…

Soildworks学习笔记(一)

1.如何添加M3,M4等螺丝孔: 有时候异形孔向导显示灰色是因为没有退出草图选项卡,选择异形孔向导就可以进行异形孔的设定和放置: solidwork放置螺丝孔以及显示螺纹的问题_.16-m3 solidwork-CSDN博客 2.如何修剪线条: 如何倒圆角或…

Hack The Box-Blurry

总体思路 CVE-2024-24590->修改脚本/劫持python库 信息收集&端口利用 nmap -sSVC blurry.htbStarting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-10 21:40 EDT Nmap scan report for app.blurry.htb (10.10.11.19) Host is up (0.20s latency).PORT STATE S…

网络仿真方法综述

目录 1. 引言 2.仿真器介绍 2.1 NS-2 2.2 NS-3 2.3 OPNET 2.4 GNS3 3.仿真对比 4.结论 参考文献 1. 引言 网络仿真是指使用计算机模拟网络系统的行为和性能的过程。在网络仿真中,可以建立一个虚拟的网络环境,并通过模拟各种网络设备、协议和应用程…

Java 的循环

Java 有三种循环&#xff1a;for&#xff0c;while&#xff0c;do while。 for 基本语法&#xff1a; for (循环变量初始化; 循环条件; 循环变量迭代){循环语句; }程序示例&#xff1a; public static void main(String[] args) {for (int i 0, j 0; i < 3; i, j--) {…