Python 中的 __str__ 与 __repr__
在 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}
但是,当我们传递使用自定义类定义定义的对象时,输出是不可理解的。为了观察这一点,让我们定义一个具有属性 name
和 age
的 Student
类。
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__()
方法来生成人类可读的对象表示,除了通知用户之外,该对象在程序中没有任何用处。
相关文章
Django 中的 Slug
发布时间:2023/05/04 浏览次数:173 分类:Python
-
本篇文章旨在定义一个 slug 以及我们如何使用 slug 字段在 Python 中使用 Django 获得独特的帖子。
在 Django 中按降序过滤查询集中的项目
发布时间:2023/05/04 浏览次数:157 分类:Python
-
在这个讲解中,学习如何借助 Django 中的 order_by() 方法按降序过滤出查询集中的项目。
Django ALLOWED_HOSTS 介绍
发布时间:2023/05/04 浏览次数:181 分类:Python
-
本文展示了如何创建您的 Django 网站,为公开发布做好准备,如何设置 ALLOWED_HOSTS 以及如何在使用 Django 进行 Web 部署期间修复预期的主要问题。
Django 中的 Select_related 方法
发布时间:2023/05/04 浏览次数:129 分类:Python
-
本文介绍了什么是查询集,如何处理这些查询以及我们如何利用 select_related() 方法来过滤 Django 中相关模型的查询。
使用 Post 请求将数据发送到 Django 服务器
发布时间:2023/05/04 浏览次数:159 分类:Python
-
在这篇关于Django的讲解中,我们简要介绍了post和get请求以及如何在Django中用post实现CSRF token。
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 中进行多项选择。