叼花硬汉 2009-09-16 20:27 采纳率: 0%
浏览 424
已采纳

和 repr 之间的区别?

What is the difference between __str__ and __repr__ in Python?

转载于:https://stackoverflow.com/questions/1436703/difference-between-str-and-repr

  • 写回答

21条回答 默认 最新

  • 胖鸭 2010-04-12 16:56
    关注

    Alex summarized well but, surprisingly, was too succinct.

    First, let me reiterate the main points in Alex’s post:

    • The default implementation is useless (it’s hard to think of one which wouldn’t be, but yeah)
    • __repr__ goal is to be unambiguous
    • __str__ goal is to be readable
    • Container’s __str__ uses contained objects’ __repr__

    Default implementation is useless

    This is mostly a surprise because Python’s defaults tend to be fairly useful. However, in this case, having a default for __repr__ which would act like:

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

    would have been too dangerous (for example, too easy to get into infinite recursion if objects reference each other). So Python cops out. Note that there is one default which is true: if __repr__ is defined, and __str__ is not, the object will behave as though __str__=__repr__.

    This means, in simple terms: almost every object you implement should have a functional __repr__ that’s usable for understanding the object. Implementing __str__ is optional: do that if you need a “pretty print” functionality (for example, used by a report generator).

    The goal of __repr__ is to be unambiguous

    Let me come right out and say it — I do not believe in debuggers. I don’t really know how to use any debugger, and have never used one seriously. Furthermore, I believe that the big fault in debuggers is their basic nature — most failures I debug happened a long long time ago, in a galaxy far far away. This means that I do believe, with religious fervor, in logging. Logging is the lifeblood of any decent fire-and-forget server system. Python makes it easy to log: with maybe some project specific wrappers, all you need is a

    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)
    

    But you have to do the last step — make sure every object you implement has a useful repr, so code like that can just work. This is why the “eval” thing comes up: if you have enough information so eval(repr(c))==c, that means you know everything there is to know about c. If that’s easy enough, at least in a fuzzy way, do it. If not, make sure you have enough information about c anyway. I usually use an eval-like format: "MyClass(this=%r,that=%r)" % (self.this,self.that). It does not mean that you can actually construct MyClass, or that those are the right constructor arguments — but it is a useful form to express “this is everything you need to know about this instance”.

    Note: I used %r above, not %s. You always want to use repr() [or %r formatting character, equivalently] inside __repr__ implementation, or you’re defeating the goal of repr. You want to be able to differentiate MyClass(3) and MyClass("3").

    The goal of __str__ is to be readable

    Specifically, it is not intended to be unambiguous — notice that str(3)==str("3"). Likewise, if you implement an IP abstraction, having the str of it look like 192.168.1.1 is just fine. When implementing a date/time abstraction, the str can be "2010/4/12 15:35:22", etc. The goal is to represent it in a way that a user, not a programmer, would want to read it. Chop off useless digits, pretend to be some other class — as long is it supports readability, it is an improvement.

    Container’s __str__ uses contained objects’ __repr__

    This seems surprising, doesn’t it? It is a little, but how readable would

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

    be? Not very. Specifically, the strings in a container would find it way too easy to disturb its string representation. In the face of ambiguity, remember, Python resists the temptation to guess. If you want the above behavior when you’re printing a list, just

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

    (you can probably also figure out what to do about dictionaries.

    Summary

    Implement __repr__ for any class you implement. This should be second nature. Implement __str__ if you think it would be useful to have a string version which errs on the side of more readability in favor of more ambiguity.

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(20条)
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 MAX98357a(关键词-播放音频)
  • ¥15 Linux误删文件,请求帮助
  • ¥15 IBMP550小型机使用串口登录操作系统
  • ¥15 关于#python#的问题:现已知七自由度机器人的DH参数,利用DH参数求解机器人的逆运动学解目前使用的PSO算法
  • ¥15 发那科机器人与设备通讯配置
  • ¥15 Linux环境下openssl报错
  • ¥15 我在使用VS编译并执行之后,但是exe程序会报“无法定位程序输入点_kmpc_end_masked于动态链接库exe上“,请问这个问题有什么解决办法吗
  • ¥15 el-select光标位置问题
  • ¥15 单片机 TC277 PWM
  • ¥15 在更新角色衣服索引后,Sprite 并未正确显示更新的效果该如何去解决orz(标签-c#)
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部