【问题标题】:What differences are between `format()` and `str()`?`format()` 和 `str()` 之间有什么区别?
【发布时间】:2019-10-17 14:31:26
【问题描述】:
>>> format(sys.stdout)
"<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>"
>>> str(sys.stdout)
"<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>"

我不太确定 Python 库引用中的以下引用。 format()str() 之间或 object.__format__(self, format_spec)object.__str__(self ) 之间有什么区别?我们什么时候用哪个?

object.__str__(self )

由 str(object) 和内置函数 format() 和 print() 调用 计算“非正式”或可很好打印的字符串表示 一个东西。

object.__format__(self, format_spec)

由 format() 内置函数调用,并通过扩展调用求值 格式化字符串文字和 str.format() 方法,以生成 对象的“格式化”字符串表示。

【问题讨论】:

  • 纯粹出于好奇。你知道repr(sys.stdout)的用途吗?它也是一个类的字符串表示。如果你不知道我也可以把它放在答案中......

标签: python python-3.x io


【解决方案1】:

我将分解主要的三个(技术上主要是 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)

好的,您可以将您的课程格式化为strrepr,但是如果您想以自己的方式格式化它怎么办?大多数人不需要这样做。但是,这就是 python 的力量,你可以做任何事情。我们可以创建不同的标签来代替rs(虽然它使用:而不是!):

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 的用例还不错)。这里的一切只是为了展示strreprformat 魔术方法之间的广泛区别。如果我有任何问题(尤其是 __format__ 的用例),请告诉我,我会更新它。

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2016-10-07
    相关资源
    最近更新 更多