__repr__

 

 

http://stackoverflow.com/questions/1436703/difference-between-str-and-repr-in-python

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 soeval(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.

share | improve this answer
 
31  
Wow, this answer is really good  –    Casebash   Apr 13 '10 at 2:08
8  
+1 for taking time to explain for others and also for the blog post!  –    Jeffrey Jose   Apr 14 '10 at 1:34
23  
You had me until you said you don't believe in debuggers. I don't know what scars you have from gdb or Eclipse but the debugger in Visual Studio is magical. Hell, I have even debugged Assembler programs in Visual Studio. If you have used the VS debugger and don't like it - you're not holding it correctly. (And you can even write/debug Python applications in VS).  –    Nathan Adams   Aug 7 '12 at 4:41
6  
As long as messages are classed correctly, I encourage logging as if there's going to be a critical failure at any time. However, you won't always have the logging you need, especially if you're just trying to understand someone else's project, and especially if the flow isn't clear. You're also not necessarily going to be able to pollute the code in production, or even see the code (if it's a compiled language). Logging and debugging are complimentary components in the toolbag of a successful engineer. Embrace every technique you can, to solve the problem at hand with brutal efficiency.  –    Dustin Oprea   Sep 17 '12 at 2:46
1  
Also, you should never, ever, ever use eval().  –    darkfeline   Jun 4 at 7:03
show 4 more comments

Unless you specifically act to ensure otherwise, most classes don't have helpful results for either:

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

As you see -- no difference, and no info beyond the class and object's id. If you only override one of the two...:

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

as you see, if you override __repr__, that's ALSO used for __str__, but not vice versa.

Other crucial tidbits to know: __str__ on a built-on container uses the __repr__, NOT the__str__, for the items it contains. And, despite the words on the subject found in typical docs, hardly anybody bothers making the __repr__ of objects be a string that eval may use to build an equal object (it's just too hard, AND not knowing how the relevant module was actually imported makes it actually flat out impossible).

So, my advice: focus on making __str__ reasonably human-readable, and __repr__ as unambiguous as you possibly can, even if that interferes with the fuzzy unattainable goal of making__repr__'s returned value acceptable as input to __eval__!

share | improve this answer
 
3  
In my unit tests I always check that eval(repr(foo)) evaluates to an object equal to foo. You're right that it won't work outside of my test cases since I don't know how the module is imported, but this at least ensures that it works in some predictable context. I think this a good way of evaluating if the result of__repr__ is explicit enough. Doing this in a unit test also helps ensure that __repr__ follows changes to the class.  –    Series8217   Nov 15 '11 at 19:58
 
Hats off to plain and simple answer !  –    Yugal Jindle   Mar 28 '12 at 5:55

__repr__: representation of python object usually eval will convert it back to that object

__str__: is whatever you think is that object in text form

e.g.

>>> 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
share | improve this answer
 
14  
Also __str__ defaults to __repr__ if no __str__ is implemented.  –    Jason R. Coombs   Sep 17 '09 at 17:14
1  
+1 because simple and you mention, that str is for translating the object to str, like int converts it to int.  –  Joschua   Jul 1 '10 at 14:50
1  
Excellent example!  –    Sergey   Jan 2 '12 at 1:44

My rule of thumb: __repr__ is for developers, __str__ is for customers.

share | improve this answer
 

In all honesty, eval(repr(obj)) is never used. If you find yourself using it, you should stop, becauseeval is dangerous, and strings are a very inefficient way to serialize your objects (use pickleinstead).

Therefore, I would recommend setting __repr__ = __str__. The reason is that str(list) callsrepr on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr will probably not be very helpful as the output of print [your, objects].

To qualify this, in my experience, the most useful use case of the repr function is to put a string inside another string (using string formatting). This way, you don't have to worry about escaping quotes or anything. But note that there is no eval happening here.

share | improve this answer
 

From http://pyref.infogami.com/%5F%5Fstr%5F%5F by effbot:

__str__ "computes the "informal" string representation of an object. This differs from __repr__ in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead."

share | improve this answer
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值