迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Python >

Python 中的 __str__ 与 __repr__

作者:迹忆客 最近更新:2023/03/01 浏览次数:

在 Python 中,我们通常使用 str() 函数将任何对象转换为字符串。类似地,我们可以使用 repr() 函数获取对象的字符串表示形式。为了让 str()repr() 产生输出,传递给这些函数的对象必须分别具有 __str__() 方法和 __repr__() 方法的实现。

通常,开发人员对这些方法的功能和用例感到困惑。在本教程中,我们将讨论 str() 函数和 repr() 函数如何工作以及 __str__() 方法和 __repr__() 方法如何影响对象的行为。

str() 函数用于获取对象的字符串表示形式。它将对象作为输入参数并返回其字符串表示形式。例如,我们可以获得浮点数的字符串表示,如下例所示。

myNum = 123.456
myStr = str(myNum)
print("The number is:", myNum)
print("The string is:", myStr)

输出:

The number is: 123.456
The string is: 123.456

类似地,我们可以使用 str() 函数将其他内置数据类型的对象(例如整数、列表、集合、元组等)转换为它们各自的字符串表示形式,如下所示。

myNum = 123
myList = [1, 2, 3, 4, 5]
mySet = {1, 2, 3, 4, 5}
myStr1 = str(myNum)
myStr2 = str(myList)
myStr3 = str(mySet)

print("The number is:", myNum)
print("The string is:", myStr1)
print("The list is:", myList)
print("The string is:", myStr2)
print("The set is:", mySet)
print("The string is:", myStr3)

输出:

The number is: 123
The string is: 123
The list is: [1, 2, 3, 4, 5]
The string is: [1, 2, 3, 4, 5]
The set is: {1, 2, 3, 4, 5}
The string is: {1, 2, 3, 4, 5}

但是,当我们传递使用自定义类定义定义的对象时,输出是不可理解的。为了观察这一点,让我们定义一个具有属性 nameageStudent 类。

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


student1 = Student("Aditya", 23)
myStr = str(student1)
print("The string representation of student object is:")
print(myStr)

输出:

The string representation of student object is:
<__main__.Student object at 0x7f6016100070>

在这里,你可以看到函数的输出不像我们转换使用内置数据结构定义的对象时那样容易理解。为什么会这样?

当我们将对象传递给 str() 函数时,将调用类定义中定义的 __str__() 方法。__str__() 方法返回对象的字符串表示。str() 函数然后返回相同的字符串。然而,当我们定义一个自定义类时,并没有 __str__() 方法。因此,str() 函数的输出不是很容易理解。

根据我们的要求,我们可以在任何类定义中实现 __str__() 方法。这里唯一的限制是该方法必须返回一个字符串值。例如,我们可以为 Student 类实现 __str__() 方法,如下所示。

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

    def __str__(self):
        myString = "Name: {} , Age: {}".format(self.name, self.age)
        return myString

在实现 __str__() 方法后,当我们将任何 Student 对象传递给 str() 函数时,它返回的字符串与 __str__() 方法返回的字符串相同。下面的例子展示了它是如何工作的。

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

    def __str__(self):
        myString = "Name: {} , Age: {}".format(self.name, self.age)
        return myString


student1 = Student("Aditya", 23)
myStr = str(student1)
print("The string representation of student object is:")
print(myStr)

输出:

The string representation of student object is:
Name: Aditya , Age: 23

你可以以任何方式实现 __str__() 方法。例如,我们可以用另一种方式定义 Student 类的 __str__() 方法,如下所示。

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

    def __str__(self):
        myString = "Name of student is: {} ,{} is {} years old".format(self.name, self.name, self.age)
        return myString


student1 = Student("Aditya", 23)
myStr = str(student1)
print("The string representation of student object is:")
print(myStr)

输出:

The string representation of student object is:
Name of student is: Aditya ,Aditya is 23 years old

我们如何实现 __str__() 方法不会影响程序的执行。__str__() 方法的输出仅用于向用户显示输出。

repr() 函数用于获取任何对象的正式字符串表示。它还将对象作为输入并返回对象的字符串表示形式,如下所示。

myNum = 123
myList = [1, 2, 3, 4, 5]
mySet = {1, 2, 3, 4, 5}
myStr1 = repr(myNum)
myStr2 = repr(myList)
myStr3 = repr(mySet)

print("The number is:", myNum)
print("The string is:", myStr1)
print("The list is:", myList)
print("The string is:", myStr2)
print("The set is:", mySet)
print("The string is:", myStr3)

输出:

The number is: 123
The string is: 123
The list is: [1, 2, 3, 4, 5]
The string is: [1, 2, 3, 4, 5]
The set is: {1, 2, 3, 4, 5}
The string is: {1, 2, 3, 4, 5}

你可以观察到 repr() 函数的输出与 str() 函数的输出几乎相同。但是,两种方法的工作方式完全不同。当我们将任何对象传递给 str() 函数时,__str__() 方法将被调用。另一方面,当我们将任何对象传递给 repr() 函数时,__repr__() 方法将被调用。下面的例子展示了它是如何工作的。

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

    def __str__(self):
        myString = "Name of student is: {} ,{} is {} years old".format(self.name, self.name, self.age)
        return myString


student1 = Student("Aditya", 23)
myStr1 = str(student1)
myStr2 = repr(student1)
print("The string representation of student object is:")
print(myStr1)
print("The output of repr() is:")
print(myStr2)

输出:

The string representation of student object is:
Name of student is: Aditya ,Aditya is 23 years old
The output of repr() is:
<__main__.Student object at 0x7f6410b78070>

我们在这里用 __str__() 方法定义了 Student 类。如果我们将 Student 类的实例传递给 str() 函数和 repr() 函数,你可以观察到输出是不同的。

str() 函数返回由 __str__() 方法返回的输出,而 repr() 函数返回由 __repr__() 方法返回的输出。如果我们不实现 __str__() 方法,str() 函数也会返回 __repr__() 方法的输出。

__repr__() 方法返回 Python 中对象的规范表示。__repr__() 方法适用于 python 中的所有对象,无论它们是内置类还是自定义类的实例。对于使用自定义类定义的对象,你可以理解 __repr__() 方法的定义,如下所示。

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

这里,self.__module 表示创建当前对象的模块,type(self).__name__ 表示类的名称,hex(id(self)) 表示对象的身份十六进制格式。下面的例子展示了它是如何工作的。

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

    def __str__(self):
        myString = "Name of student is: {} ,{} is {} years old".format(self.name, self.name, self.age)
        return myString


student1 = Student("Aditya", 23)
myStr = student1.__repr__()
print("The output of __repr__() is:")
print(myStr)

输出:

The output of __repr__() is:
<__main__.Student object at 0x7feb92cc8070>

在这里,你可以看到 __repr__() 方法的输出类似于方法定义中定义的模式。输出显示该对象已在 __main__ 模块中定义并且属于 Student 类。输出还显示了对象的身份。

你应该始终避免覆盖 __repr__() 方法。这是因为 __repr__() 方法用于创建对象的规范字符串表示,借助它我们可以重新实例化相同的对象。

但是,如果我们重写 __repr__() 方法,我们将无法使用 eval() 函数从其字符串表示创建对象。
正如我们已经讨论了 __str__() 方法和 __repr__() 方法的基础知识,让我们列出这两种方法之间的一些区别。

__str__() 方法返回开发人员可以自定义的对象的用户可读字符串形式。但是,__repr__() 方法返回字符串的规范字符串表示。在某些情况下,__str__() 方法返回的字符串可能与 __repr__() 方法返回的字符串相同。你可以在数字的情况下观察到这一点。

但是,当我们使用自定义类定义获取字符串或对象时,__repr__() 方法返回的字符串与 __str__() 方法返回的字符串不同。下面的例子展示了它是如何工作的。

myStr = "Aditya"
myStr1 = myStr.__repr__()
myStr2 = myStr.__str__()
print("The string is:", myStr)
print("The output from the __repr__() method is:", myStr1)
print("The output from the __str__() method is:", myStr2)

输出:

The string is: Aditya
The output from the __repr__() method is: 'Aditya'
The output from the __str__() method is: Aditya

在这里,你可以观察到 __str__() 方法返回的字符串是 Aditya。另一方面,__repr__() 方法返回规范字符串表示'Aditya'

myNum = 1234
myNum1 = myNum.__repr__()
myNum2 = myNum.__str__()
print("The number is:", myNum)
print("The output from the __repr__() method is:", myNum1)
print("The output from the __str__() method is:", myNum2)
output1 = eval(myNum1)
print(output1)
output2 = eval(myNum2)
print(output2)

输出:

The number is: 1234
The output from the __repr__() method is: 1234
The output from the __str__() method is: 1234
1234
1234

在这里,你可以观察到我们可以从使用 __str__() 方法和 __repr__() 方法获得的整数的字符串表示中获得整数对象。现在,看看下面的例子。

myStr = "Aditya"
myStr1 = myStr.__repr__()
myStr2 = myStr.__str__()
print("The string is:", myStr)
print("The output from the __repr__() method is:", myStr1)
print("The output from the __str__() method is:", myStr2)
output1 = eval(myStr1)
print(output1)
output2 = eval(myStr2)
print(output2)

输出:

The string is: Aditya
The output from the __repr__() method is: 'Aditya'
The output from the __str__() method is: Aditya
Aditya
/usr/lib/python3/dist-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (3.0.4) doesn't match a supported version!
  warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
Traceback (most recent call last):
  File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 9, in <module>
    output2 = eval(myStr2)
  File "<string>", line 1, in <module>
NameError: name 'Aditya' is not defined

你可以看到我们可以从 __repr__() 方法返回的字符串创建一个字符串对象。但是,当我们尝试使用 __str__() 方法返回的字符串创建字符串对象时,程序会遇到 NameError 异常。

在本文中,我们讨论了 str() 函数、__str__() 方法、repr() 函数和 __repr__() 方法的工作原理。我们还讨论了使用 __str__() 方法和 __repr__() 方法之间的区别。

尽管两种方法的输出相似,但存在明显的差异,使 __repr__() 方法和 __str__() 方法彼此非常不同。当你需要使用字符串表示重新实例化对象时,我建议你使用 __repr__() 方法来获取对象的字符串表示。

另一方面,你应该使用 __str__() 方法来生成人类可读的对象表示,除了通知用户之外,该对象在程序中没有任何用处。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Django 中的 Slug

发布时间:2023/05/04 浏览次数:173 分类:Python

本篇文章旨在定义一个 slug 以及我们如何使用 slug 字段在 Python 中使用 Django 获得独特的帖子。

Django ALLOWED_HOSTS 介绍

发布时间:2023/05/04 浏览次数:181 分类:Python

本文展示了如何创建您的 Django 网站,为公开发布做好准备,如何设置 ALLOWED_HOSTS 以及如何在使用 Django 进行 Web 部署期间修复预期的主要问题。

Django 中的 Select_related 方法

发布时间:2023/05/04 浏览次数:129 分类:Python

本文介绍了什么是查询集,如何处理这些查询以及我们如何利用 select_related() 方法来过滤 Django 中相关模型的查询。

在 Django 中上传媒体文件

发布时间:2023/05/04 浏览次数:198 分类:Python

在本文中,我们简要介绍了媒体文件以及如何在 Django 项目中操作媒体文件。

Django 返回 JSON

发布时间:2023/05/04 浏览次数:106 分类:Python

在与我们的讨论中,我们简要介绍了 JSON 格式,并讨论了如何借助 Django 中的 JsonResponse 类将数据返回为 JSON 格式。

在 Django 中创建对象

发布时间:2023/05/04 浏览次数:59 分类:Python

本文的目的是解释什么是模型以及如何使用 create() 方法创建对象,并了解如何在 Django 中使用 save() 方法。

在 Django 中为多项选择创建字段

发布时间:2023/05/04 浏览次数:75 分类:Python

在本文中,我们将着眼于为多项选择创建一个字段,并向您展示如何允许用户在 Django 中进行多项选择。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便