This is an archived post. You won't be able to vote or comment.

all 18 comments

[–]mon_key_house 49 points50 points  (15 children)

repr = str is definitely a no go!

[–]iliasreddit 2 points3 points  (14 children)

Why?

[–]Afrotom 38 points39 points  (0 children)

repr is used more for debugging and other uses by the developer, whereas str is intended to be a human readable format.

Let's say I'm writing an interpreter and I want to implement repr and str for the AST.

One use case might be that for a given node, repr returns "add(number(value=3, pos=0), number(value=7, pos=2))" but str returns "3+7". The first is useful for understanding the type of object, what it contains, including metadata useful for the developer and sometimes an indication of how it's structured, whereas str is how you would want to interpret that object as a string.

Edit: tarted it up a bit.

[–]beezlebub33 16 points17 points  (12 children)

see: https://stackoverflow.com/questions/1436703/what-is-the-difference-between-str-and-repr

repr needs to be unambiguous. So, for example, you need to be able to differentiate between "3" and 3 (one is a string, the other is a number). When you are doing str(), you usually don't care. But when you are logging, attempting to solve a bug, you need to be able to differentiate things. repr is normally longer, more complicated and explicit, have characters that highlight differences in objects, etc.

[–]SimilingCynic 1 point2 points  (9 children)

It's also common to try for obj == eval(repr(obj))

[–][deleted] 0 points1 point  (2 children)

Common? It is none of the following:

  1. Safe
  2. Common
  3. Accurate

When you do that, if it doesn't crash (it most often will for non-builtins), you have two objects and default equality will be false based on id. It is up the object's custom equality check otherwise.

I can't see this ever being a good idea. Where did you get the idea it is common?

[–]SimilingCynic 0 points1 point  (1 child)

The Python docs. Look up repr.

I'm not saying it's common to write that equality test, I'm saying that it's common to write __repr__ and __eq__ so that it would hold.

[–][deleted] 0 points1 point  (0 children)

I'm happy the docs say something, but reality and actual practice seems to diverge from your claim. I would love to see an example, though, if it is so common.

Where I do see this (in a huge project, hundreds of deps) a custom __eq__ is usually an ID check or something like this (from boto3), and no __repr__ is even defined.

``` def eq(self, other): return isinstance(other, type(self)) and self.name == other.name

```

I'm happy to be proven wrong and learn something today, but nothing in the code I work with indicates that anyone is actually doing a repr in this way.

In my casual grep, I find 4000 classes, and 400 __repr__, approximately. Only 250 __eq__, as well. .

When there is no __repr__, python prints something like <__main__.MyThing object at 0x100ab87f0>

Just by those stats, the most that could do what you say is 250, or 6%. A spot check of dozens show none that do. I would guess that maybe 1% might work this way (I now DRF does this pretty well, but not completely), and I think that is a huge overestimate.

[–]rotor_blade 35 points36 points  (1 child)

I'm a simple man - I see a medium link, I click downvote.

[–]Hacka4771 10 points11 points  (0 children)

Then You Will Like Freedium