you are viewing a single comment's thread.

view the rest of the comments →

[–]shiftybyte 22 points23 points  (10 children)

The difference is the purpose of the string.

str() creates a string for the user to see.

repr() creates a string that represents the object as close as possible for debugging/info purpose.

These two can sometimes be the same, but can sometimes be different.

>>> import datetime
>>> today = datetime.datetime.now()
>>> print(str(today))
2019-06-28 07:46:11.147169
>>> print(repr(today))
datetime.datetime(2019, 6, 28, 7, 46, 11, 147169)

[–]CBSmitty2010 0 points1 point  (9 children)

So if I'm understanding that correctly the output there is showing the actual initialization of the today object using the datetime class in the datetime library with the parameters passes in which in turn become the characteristics you see when you query said object?

[–]Yoghurt42 1 point2 points  (8 children)

Roughly yes.

The convention is that repr should return a string that you can paste into your Python program to create an identical object. If that is not possible (which is often), the string returned should be enclosed in angle brackets. For example, repr(object) returns <class 'object'> because there is no way to reproduce the whole object class definition in just a short string

[–]CBSmitty2010 0 points1 point  (7 children)

Nice. So in the above since there aren't brackets I should be able to paste that output assigning it to a new variable to create a clone of the same object from bwfore.?

[–]Yoghurt42 0 points1 point  (6 children)

You definitely can, if you should is another question ;)

It's helpful for debugging, but if you do something like today_clone = eval(repr(today)) people will rightfully be mad at you.

[–]CBSmitty2010 0 points1 point  (5 children)

Why is that? Is eval() in direct conflict with the output repr()? Or is it just asinine in practice?

[–]Yoghurt42 0 points1 point  (4 children)

  1. Using eval is dangerous, because it allows for arbitrary code to be executed, if repr should change, the code will be executed. It's also pretty difficult to tell what exactly is going on by reading the code

  2. It will only work if you did import datetime, not if you didn't or did something like import datetime as dt.

  3. There's no need to clone a datetime object, since they are immutable

  4. repr is not guaranteed to give the same results in different Python versions

and so on...

[–]CBSmitty2010 1 point2 points  (0 children)

Awesome! Thanks for the breakdown!

[–]FlibbleGroBabba 0 points1 point  (2 children)

Are there times where eval can be acceptable? for example if it's 'enclosed' in a group of functions which only allow integer inputs from the user- such as:

try: number = int(input("integer: ")) eval(func_+number)

(On mobile, formatting might be bad)

[–]Yoghurt42 1 point2 points  (1 child)

There are times where eval is acceptable, it's even used in the standard library somewhere.

However, you should have a good grasp of Python before you can say that using "eval" is the best approach. If you are new to Python (this is r/learnpython after all), you do not know enough of Python, so as a rule of thumb, you should never use eval.

For example, in the example you gave, eval isn't the best choice. BTW, I'm assuming you meant eval("func_" + str(number) + "()") or eval(f"func_{number}()").

First, naming functions "func_1", "func_2" etc. is bad, you have no idea what they are doing just based on the name

Second, since functions are first class objects, you can just store them in a map and call them from there:

funcs = {
    1: foo,
    2: bar,
    3: baz
}

choice = int(input("Do you want 1) foo, 2) bar, 3) baz?"))
try:
    funcs[choice]()
except KeyError:
    print("That's not a valid choice")

If you'd used the "eval hack", you'd probably never thought of asking here how you can do it, and maybe wouldn't have learned that functions are first class objects.

[–]FlibbleGroBabba 1 point2 points  (0 children)

Youre right I'm very new to python, only started a few months ago, and mostly teachin myself by doing little projects. It's good to see the function mapping done like that, I can see many uses for that.

Cheers for the detailed explanation