代码之家  ›  专栏  ›  技术社区  ›  Casebash

__str__和__repr__有什么区别?

  •  3636
  • Casebash  · 技术社区  · 16 年前

    两者之间有什么区别 __str__ __repr__ Python?

    28 回复  |  直到 3 年前
        1
  •  39
  •   wescpy    2 年前

    Alex Martelli summarized well 但令人惊讶的是,它太简洁了。

    Alex s职位:

    • 默认的实现是无用的(很难想象有什么是无用的,但确实如此)
    • __repr__ 目标是明确无误
    • __str__
    • 容器 __str__ 使用包含的对象 __代表__

    这主要是一个惊喜,因为Python的默认值往往相当有用。但是,在这种情况下,默认为 __代表__ 其行为方式如下:

    return "%s(%r)" % (self.__class__, self.__dict__)
    

    这太危险了(例如,如果对象相互引用,就太容易陷入无限递归)。所以Python退出了。请注意,有一个默认值为true:如果 __代表__ __str__ 如果不是,对象将表现得好像 __str__=__repr__ .

    __代表__ __str__

    ……的目标 __代表__ 要毫不含糊

    log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)
    

    eval(repr(c))==c ,这意味着你知道所有需要知道的事情 c 。如果这很容易,至少以一种模糊的方式,那就去做。如果不容易,确保你有足够的信息 "MyClass(this=%r,that=%r)" % (self.this,self.that)

    %r %s repr() r 格式化字符,等效地]内部 __代表__ 实施,否则你就无法实现销售代表的目标。你希望能够实现差异化 MyClass(3) MyClass("3") .

    ……的目标 __str__ 应可读

    具体来说,这并不是一个明确的通知 str(3)==str("3") 同样,如果你实现了一个IP抽象,让它的str看起来像192.168.1.1就可以了。在实现日期/时间抽象时,str可以是“2010/4/12 15:35:22”,等等。目标是以用户而非程序员想要阅读的方式表示它。剪掉无用的数字,假装是其他类,只要它支持可读性,这就是一种改进。

    容器 __str__ 使用包含的对象 __代表__

    __str__ ?

    [moshe is, 3, hello
    world, this is a list, oh I don't know, containing just 4 elements]
    

    不太好。具体来说,容器中的字符串很容易干扰其字符串表示。面对歧义,记住,Python抵制猜测的诱惑。如果你想在打印列表时有上述行为,只需

    print("[" + ", ".join(lst) + "]")
    

    (你可能也能弄清楚如何处理字典)。

    总结

    __代表__ 对于你实现的任何类。这应该是第二天性。实施 __str__ 如果你认为有一个在可读性方面出错的字符串版本是有用的。

        2
  •  10
  •   JonnyRobbie    4 年前

    我的经验法则是: __repr__ __str__ 这是为了客户。

        3
  •  3
  •   Yilmaz    5 年前

    除非你特别采取行动确保其他情况,否则大多数类对以下两种情况都没有帮助:

    >>> class Sic(object): pass
    ... 
    >>> print(str(Sic()))
    <__main__.Sic object at 0x8b7d0>
    >>> print(repr(Sic()))
    <__main__.Sic object at 0x8b7d0>
    

    如您所见,没有区别,除了类和对象之外没有其他信息 id 。如果您只覆盖其中一个:

    >>> class Sic(object): 
    ...   def __repr__(self): return 'foo'
    ... 
    >>> print(str(Sic()))
    foo
    >>> print(repr(Sic()))
    foo
    >>> class Sic(object):
    ...   def __str__(self): return 'foo'
    ... 
    >>> print(str(Sic()))
    foo
    >>> print(repr(Sic()))
    <__main__.Sic object at 0x2617f0>
    

    正如你所看到的,如果你覆盖 __repr__ __str__

    其他需要了解的关键信息: __str__ __代表__ __str__ __代表__ 对象是一个字符串 eval 可以用来构建一个相等的对象(这太难了,而且不知道相关模块是如何实际导入的,这实际上是不可能的)。

    __str__ __代表__ 尽可能明确,即使这会干扰模糊的、无法实现的目标 __代表__ 评估 !

        4
  •  3
  •   Vlad Bezden    3 年前

    __repr__

    __str__ :你认为那个物体是文本形式的吗

    例如

    >>> s="""w'o"w"""
    >>> repr(s)
    '\'w\\\'o"w\''
    >>> str(s)
    'w\'o"w'
    >>> eval(str(s))==s
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1
        w'o"w
           ^
    SyntaxError: EOL while scanning single-quoted string
    >>> eval(repr(s))==s
    True
    
        5
  •  2
  •   Shaiful Islam    3 年前

    简而言之,目标 __repr__ __str__ 可读性。

    >>> import datetime
    >>> today = datetime.datetime.now()
    >>> str(today)
    '2012-03-14 09:21:58.130922'
    >>> repr(today)
    'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'
    

    阅读此报告文档:

    repr(object)

    返回一个包含对象可打印表示的字符串。这与转换产生的值相同(相反 引用)。有时,能够以以下方式访问此操作是有用的 一个普通的功能。对于许多类型,此函数会尝试 返回一个字符串,该字符串将在以下情况下产生具有相同值的对象 eval() 包含对象类型名称的尖括号 以及通常包括姓名和 对象的地址。类可以控制此函数返回什么 __repr__() 方法。

    以下是str的文档:

    str(object='')

    返回一个包含可良好打印的字符串 对象的表示。对于字符串,这将返回字符串 本身。区别在于 repr(对象) str(object) 始终尝试返回一个可接受的字符串 eval() ;其 目标是返回一个可打印的字符串。如果没有给出参数,则返回 空字符串, '' .

        6
  •  1
  •   barii    3 年前

    __str__ __repr__ Python?

    __str__ (读作“dunder(双下划线)字符串”)和 __代表__

    __代表__ __str__ 不见了。

    __代表__ eval

    在任何时候,人们都可以写一个 __str__ 对于实例的用户可读字符串表示,当人们认为有必要时。

    __str__

    format , str.format ,或 str ,那么如果a __str__ __代表__ 将被使用。

    __代表__

    __代表__ 方法由内置函数调用 repr 当python shell计算一个返回对象的表达式时,它会在python shell上反射。

    __str__ __代表__

    这是内置的帮助 表示 :

    repr(...)
        repr(object) -> string
        
        Return the canonical string representation of the object.
        For most object types, eval(repr(object)) == object.
    

    表示 但这不是默认实现。

    默认执行 __代表__

    __代表__ 是( C Python source )类似于:

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

    这意味着默认情况下,您将打印对象来自的模块、类名及其在内存中位置的十六进制表示形式,例如:

    <__main__.Foo object at 0x7f80665abdd0>
    

    这些信息不是很有用,但无法推导出如何准确地创建任何给定实例的规范表示,这总比什么都没有好,至少告诉我们如何在内存中唯一标识它。

    怎么 __代表__

    datetime 物体。首先,我们需要导入 日期时间 模块:

    import datetime
    

    如果我们打电话 datetime.now 在shell中,我们将看到重新创建等效datetime对象所需的一切。这是由日期时间创建的 __代表__ :

    >>> datetime.datetime.now()
    datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
    

    如果我们打印一个日期时间对象,我们会看到一个很好的人类可读(实际上是ISO)格式。这是由datetime实现的 __str__ :

    >>> print(datetime.datetime.now())
    2015-01-24 20:05:44.977951
    

    __代表__

    >>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
    >>> print(the_past)
    2015-01-24 20:05:36.491180
    

    #我该如何实施它们?

    __代表__ Python source ).它相当复杂,因为复制这样一个对象所需的所有属性:

    def __repr__(self):
        """Convert to formal string, for repr()."""
        L = [self._year, self._month, self._day,  # These are never zero
             self._hour, self._minute, self._second, self._microsecond]
        if L[-1] == 0:
            del L[-1]
        if L[-1] == 0:
            del L[-1]
        s = "%s.%s(%s)" % (self.__class__.__module__,
                           self.__class__.__qualname__,
                           ", ".join(map(str, L)))
        if self._tzinfo is not None:
            assert s[-1:] == ")"
            s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
        if self._fold:
            assert s[-1:] == ")"
            s = s[:-1] + ", fold=1)"
        return s
    

    如果你想让你的对象有一个更易读的表示,你可以实现 __str__ Python source )执行器 __str__ ,它很容易做到这一点,因为它已经具有以ISO格式显示的功能:

    def __str__(self):
        "Convert to string, for str()."
        return self.isoformat(sep=' ')
    

    __repr__ = __str__ ?

    这是对另一个建议设置的答案的批评 .

    设置 __代表__ __str__ 和一个 __代表__ ,为开发人员在调试中使用而编写,应在编写 __str__ .

    你需要一个 __str__

    结论

    __代表__ 对于您编写的对象,这样您和其他开发人员在开发时使用它时就可以有一个可重复的示例。定义 __str__ 当你需要一个人类可读的字符串表示时。

    推荐文章