{"id":1794,"date":"2019-04-05T08:35:25","date_gmt":"2019-04-05T07:35:25","guid":{"rendered":"https:\/\/rosetta.vn\/short\/?p=1794"},"modified":"2019-04-26T14:40:05","modified_gmt":"2019-04-26T13:40:05","slug":"python-difference-between-__str__-and-__repr__-stack-overflow","status":"publish","type":"post","link":"https:\/\/rosetta.vn\/short\/2019\/04\/05\/python-difference-between-__str__-and-__repr__-stack-overflow\/","title":{"rendered":"python &#8211; Difference between __str__ and __repr__? &#8211; Stack Overflow"},"content":{"rendered":"<p>T\u00f3m t\u1eaft: c\u1ea7n __repr__ cho m\u1ecdi class, v\u00ec c\u00e1i default c\u1ee7a Python kh\u00f4ng gi\u00fap th\u1ec3 hi\u1ec7n th\u00f4ng tin \u0111\u1ea7y \u0111\u1ee7 c\u1ee7a \u0111\u1ed1i t\u01b0\u1ee3ng.<\/p>\n<p>Gi\u00e1 tr\u1ecb tr\u1ea3 v\u1ec1 c\u1ee7a __repr__ s\u1ebd hi\u1ec7n ra khi nh\u1eadp v\u00e0o t\u00ean c\u1ee7a object instance, c\u00f2n gi\u00e1 tr\u1ecb tr\u1ea3 v\u1ec1 c\u1ee7a __str__ s\u1ebd hi\u1ec7n ra khi d\u00f9ng l\u1ec7nh print(t\u00ean c\u1ee7a object instance).<\/p>\n<p>Implement\u00a0<code>__repr__<\/code>\u00a0for any class you implement. This should be second nature. Implement\u00a0<code>__str__<\/code>\u00a0if you think it would be useful to have a string version which errs on the side of readability.<\/p>\n<p>&#8212;<\/p>\n<blockquote><p><a href=\"https:\/\/stackoverflow.com\/users\/95810\/alex-martelli\">Alex<\/a>\u00a0summarized well but, surprisingly, was too succinct.<\/p>\n<p>First, let me reiterate the main points in\u00a0<a href=\"https:\/\/stackoverflow.com\/a\/1436756\/3798217\">Alex\u2019s post<\/a>:<\/p>\n<ul>\n<li>The default implementation is useless (it\u2019s hard to think of one which wouldn\u2019t be, but yeah)<\/li>\n<li><code>__repr__<\/code>\u00a0goal is to be unambiguous<\/li>\n<li><code>__str__<\/code>\u00a0goal is to be readable<\/li>\n<li>Container\u2019s\u00a0<code>__str__<\/code>\u00a0uses contained objects\u2019\u00a0<code>__repr__<\/code><\/li>\n<\/ul>\n<p><strong>Default implementation is useless<\/strong><\/p>\n<p>This is mostly a surprise because Python\u2019s defaults tend to be fairly useful. However, in this case, having a default for\u00a0<code>__repr__<\/code>\u00a0which would act like:<\/p>\n<pre class=\"lang-py prettyprint prettyprinted\"><code><span class=\"kwd\">return<\/span> <span class=\"str\">\"%s(%r)\"<\/span> <span class=\"pun\">%<\/span> <span class=\"pun\">(<\/span><span class=\"pln\">self<\/span><span class=\"pun\">.<\/span><span class=\"pln\">__class__<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> self<\/span><span class=\"pun\">.<\/span><span class=\"pln\">__dict__<\/span><span class=\"pun\">)<\/span><\/code><\/pre>\n<p>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\u00a0<code>__repr__<\/code>is defined, and\u00a0<code>__str__<\/code>\u00a0is not, the object will behave as though\u00a0<code>__str__=__repr__<\/code>.<\/p>\n<p>This means, in simple terms: almost every object you implement should have a functional\u00a0<code>__repr__<\/code>\u00a0that\u2019s usable for understanding the object. Implementing\u00a0<code>__str__<\/code>\u00a0is optional: do that if you need a \u201cpretty print\u201d functionality (for example, used by a report generator).<\/p>\n<p><strong>The goal of\u00a0<code>__repr__<\/code>\u00a0is to be unambiguous<\/strong><\/p>\n<p>Let me come right out and say it \u2014 I do not believe in debuggers. I don\u2019t 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 \u2014 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<\/p>\n<pre class=\"lang-py prettyprint prettyprinted\"><code><span class=\"pln\">log<\/span><span class=\"pun\">(<\/span><span class=\"pln\">INFO<\/span><span class=\"pun\">,<\/span> <span class=\"str\">\"I am in the weird function and a is\"<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> a<\/span><span class=\"pun\">,<\/span> <span class=\"str\">\"and b is\"<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> b<\/span><span class=\"pun\">,<\/span> <span class=\"str\">\"but I got a null C \u2014 using default\"<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> default_c<\/span><span class=\"pun\">)<\/span><\/code><\/pre>\n<p>But you have to do the last step \u2014 make sure every object you implement has a useful repr, so code like that can just work. This is why the \u201ceval\u201d thing comes up: if you have enough information so\u00a0<code>eval(repr(c))==c<\/code>, that means you know everything there is to know about\u00a0<code>c<\/code>. If that\u2019s easy enough, at least in a fuzzy way, do it. If not, make sure you have enough information about\u00a0<code>c<\/code>anyway. I usually use an eval-like format:\u00a0<code>\"MyClass(this=%r,that=%r)\" % (self.this,self.that)<\/code>. It does not mean that you can actually construct MyClass, or that those are the right constructor arguments \u2014 but it is a useful form to express \u201cthis is everything you need to know about this instance\u201d.<\/p>\n<p>Note: I used\u00a0<code>%r<\/code>\u00a0above, not\u00a0<code>%s<\/code>. You always want to use\u00a0<code>repr()<\/code>\u00a0[or\u00a0<code>%r<\/code>\u00a0formatting character, equivalently] inside\u00a0<code>__repr__<\/code>\u00a0implementation, or you\u2019re defeating the goal of repr. You want to be able to differentiate\u00a0<code>MyClass(3)<\/code>\u00a0and\u00a0<code>MyClass(\"3\")<\/code>.<\/p>\n<p><strong>The goal of\u00a0<code>__str__<\/code>\u00a0is to be readable<\/strong><\/p>\n<p>Specifically, it is not intended to be unambiguous \u2014 notice that\u00a0<code>str(3)==str(\"3\")<\/code>. 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 &#8220;2010\/4\/12 15:35:22&#8221;, 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 \u2014 as long is it supports readability, it is an improvement.<\/p>\n<p><strong>Container\u2019s\u00a0<code>__str__<\/code>\u00a0uses contained objects\u2019\u00a0<code>__repr__<\/code><\/strong><\/p>\n<p>This seems surprising, doesn\u2019t it? It is a little, but how readable would<\/p>\n<pre class=\"lang-py prettyprint prettyprinted\"><code><span class=\"pun\">[<\/span><span class=\"pln\">moshe <\/span><span class=\"kwd\">is<\/span><span class=\"pun\">,<\/span> <span class=\"lit\">3<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> hello\r\nworld<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> this <\/span><span class=\"kwd\">is<\/span><span class=\"pln\"> a list<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> oh I don<\/span><span class=\"str\">'t know, containing just 4 elements]<\/span><\/code><\/pre>\n<p>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\u2019re printing a list, just<\/p>\n<pre class=\"lang-py prettyprint prettyprinted\"><code><span class=\"kwd\">print<\/span> <span class=\"str\">\"[\"<\/span> <span class=\"pun\">+<\/span> <span class=\"str\">\", \"<\/span><span class=\"pun\">.<\/span><span class=\"pln\">join<\/span><span class=\"pun\">(<\/span><span class=\"pln\">l<\/span><span class=\"pun\">)<\/span> <span class=\"pun\">+<\/span> <span class=\"str\">\"]\"<\/span><\/code><\/pre>\n<p>(you can probably also figure out what to do about dictionaries.<\/p>\n<p><strong>Summary<\/strong><\/p>\n<p>Implement\u00a0<code>__repr__<\/code>\u00a0for any class you implement. This should be second nature. Implement\u00a0<code>__str__<\/code>\u00a0if you think it would be useful to have a string version which errs on the side of readability.<\/p><\/blockquote>\n<p>Source: <em><a href=\"https:\/\/stackoverflow.com\/questions\/1436703\/difference-between-str-and-repr\">python &#8211; Difference between __str__ and __repr__? &#8211; Stack Overflow<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00f3m t\u1eaft: c\u1ea7n __repr__ cho m\u1ecdi class, v\u00ec c\u00e1i default c\u1ee7a Python kh\u00f4ng gi\u00fap th\u1ec3 hi\u1ec7n th\u00f4ng tin \u0111\u1ea7y \u0111\u1ee7 c\u1ee7a \u0111\u1ed1i t\u01b0\u1ee3ng. Gi\u00e1 tr\u1ecb tr\u1ea3 v\u1ec1 c\u1ee7a __repr__ s\u1ebd hi\u1ec7n ra khi nh\u1eadp v\u00e0o t\u00ean c\u1ee7a object instance, c\u00f2n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false},"categories":[30,215],"tags":[1193,47,222,1194],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p8jhJx-sW","_links":{"self":[{"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/posts\/1794"}],"collection":[{"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/comments?post=1794"}],"version-history":[{"count":3,"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/posts\/1794\/revisions"}],"predecessor-version":[{"id":1828,"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/posts\/1794\/revisions\/1828"}],"wp:attachment":[{"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/media?parent=1794"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/categories?post=1794"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rosetta.vn\/short\/wp-json\/wp\/v2\/tags?post=1794"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}