我将分解主要的三个(技术上主要是 2,因为 __format__ 不是很常见)。我将完成所有三个,然后将它们放在一个不错的课程中。
最常见的__str__:
这就是您希望将此对象表示为str 的方式。
通常这没有__repr__ 详细,并且被使用
主要面向最终用户。例如,如果我们有一个person 类,我们可以这样实现str:
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Hello my name is {self.name}"
p = Person("John Smith")
print(str(p)) # Prints "Hello my name is John Smith"
不太常见的__repr__:
老实说,对于大多数项目,我比str 实现的更多。这应该以str 的形式返回对象的表示形式,以便对开发人员 而不是最终用户有帮助,并通过repr(my_obj) 调用。如果一个类没有实现 __str__ 魔术方法,那么当你使用 str(my_obj) 时,python 将尝试自动调用它的 __repr__ 方法(因此你可以先实现 repr,然后再实现 str)。通常,类的repr 返回重新创建该对象的方式。例如:
class Person:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"Person(name='{self.name}')"
p = Person("John Smith")
print(repr(p)) # Prints "Person(name='John Smith')"
print(str(p)) # Prints "Person(name='John Smith')"
被诅咒的孩子__format__:[我只是这么称呼它,因为它太不常用了:)]
要理解这一点,我必须先解释一些格式化的东西。您可能以前见过这些东西,也可能没有。
让我们使用一个虚拟类:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'Person(name="{self.name}", age={self.age})'
def __str__(self):
return str(self.name)
p = Person(name="John Smith", age=22)
# This prints the str of p
print("{!s}".format(p)) # John Smith
# This prints the representation of p
print("{!r}".format(p)) # Person(name="John Smith", age=22)
好的,您可以将您的课程格式化为str 或repr,但是如果您想以自己的方式格式化它怎么办?大多数人不需要这样做。但是,这就是 python 的力量,你可以做任何事情。我们可以创建不同的标签来代替r和s(虽然它使用:而不是!):
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'Person(name="{self.name}", age={self.age})'
def __str__(self):
return str(self.name)
def __format__(self, format_spec):
if format_spec == 'age': # get a persons age
return f"{self.name} is {self.age} years old"
elif format_spec == 'birthday':
return "Yesterday"
return str(self) # A default case
p = Person(name="John Smith", age=22)
# This prints the str of p
print("{!s}".format(p))
# This with representation of p
print("{!r}".format(p))
print("{:age}".format(p))
print("{:birthday}".format(p))
print(f"{p:age} and his birthday was {p:birthday}")
这显然比我有限的知识所能了解的要多,但这应该是一个很好的一般范围:)。
有一些包使用这个,例如datetime。如果您有兴趣了解更多关于格式 Pyformat 的强大功能的信息,请阅读以下内容:PyFormat。
免责声明:
我没有太多使用__format__ 的经验,所以我无法提供一个好的用例(尽管 datetime 的用例还不错)。这里的一切只是为了展示str、repr 和format 魔术方法之间的广泛区别。如果我有任何问题(尤其是 __format__ 的用例),请告诉我,我会更新它。