python3: repr()、str()、eval()とは

[学校の宿題](http://cs61a.org/hw/hw01/)をしていたらQuestion7でこんな問題に:

>
Write a one-line program that prints itself, using only the following features of the Python language:
>
- Number literals
- Assignment statements
- String literals that can be expressed using single or double quotes
- The arithmetic operators +, -, *, and /
- The built-in print function
- The built-in eval function, which evaluates a string as a Python expression
- The built-in repr function, which returns an expression that evaluates to its argument
- You can concatenate two strings by adding them together with + and repeat a string by multipying it by an integer. - Semicolons can be used to separate multiple statements on the same line. E.g.,

>
```
>>> c='c';print('a');print('b' + c * 2)
a
bcc
```

Question7自体はまた別の記事で書くとして今回は`repr()`についてのみ焦点を置いて考えてみることにする。

#`repr()`とは

もともとはこんな感じ`object.__repr__(self)`。`str()`と比較しながらだとより分かりやすいかもしれない。

<a href="https://docs.python.org/3.3/reference/datamodel.html" target="_blank">pythonのオフィシャル</a>を参照に見てみると:

>
Called by the repr() built-in function to compute the “official” string representation of an object.

どうやら`__repr__`がofficial string representaionで`__str__`がinformal string representationっぽいですね。

```
>>> y = 'a string'
>>> repr(y)
"'a string'"
>>> str(y)
'a string'
```

```
>>> a = 'a'
>>> eval(str(a))
'a'
>>> eval(repr(a))
'a'
```

また<a href="http://satran.in/2012/03/14/python-repr-str.html" target="_blank">他の記事</a>では:
>
The print statement and str() built-in function uses \_\_str__ to display the string representation of the object while the repr() built-in function uses \_\_repr__ to display the object. 

```
>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2016-01-30 01:56:09.287104'
>>> repr(today)
'datetime.datetime(2016, 1, 30, 1, 56, 9, 287104)'
```

`str()`を使うとユーザーに分かりやすいように時間表示してくれる。見ただけで直感的に何時か分かる。

`repr()`でも返ってきた値はストリングだが（ここでいう）officialとして表示されている。officialというのは簡単にいえばその値を再利用できるかどうか。

```
>>> eval(repr(today))
datetime.datetime(2016, 1, 30, 1, 56, 9, 287104)
>>> eval(str(today))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    2016-01-30 01:56:09.287104
          ^
SyntaxError: invalid token
```

`eval()`はストリングを受け取ってdatetimeのオブジェクトへと変えてくれる。identifier的な。

##`repr()`周辺の理解をするために

手始めとしてクォーテーションマークのことも少しくらいは知っておいたほうがいいかと思います:

- [Python - Using quotation marks inside quotation marks](http://stackoverflow.com/questions/9050355/python-using-quotation-marks-inside-quotation-marks)
- [Python Tutorial: Strings Single, Double and Triple Quotes - Python Strings #41](https://www.youtube.com/watch?v=1KNEbpg_Kz8)

##やってくれること

簡単にいえば受け取った引数にシングルクォーテーションマークを付けて返してくれる。

```
>>> x = 1
>>> repr(x)
'1'
```

ちなみに

```
>>> x = 'a'
>>> eval(repr(x)) == x
True
```

#その他、補足

strの特徴をうまく使った関数を見つけたのでメモがてら。

##strはリストと似たような扱い方をすることができる。

###str with `for loop`
strを引数として受け取りそこにfor loopをかけて一つ一つの単語を抜き出すことができる。

```
def shout(string):
    for character in string:
        print("Gimme a " + character)
        print("'" + character + "'")

shout("Lose")
```

###str with `len()`

listと同様strにも`len()`かけて長さを図れる。ということはa番目の文字=`str[a]`をちょっといじくると単語の真ん中の文字 = その単語の長さ//2番目の単語 = `str[len(str) // 2]`になる。

```
def middle(string):
    print("The middle character is:", string[len(string) // 2])

middle("abcdefg")
middle("The Python Programming Language")
middle("Atlanta")
```

output:

```
Gimme a L
'L'
Gimme a o
'o'
Gimme a s
's'
Gimme a e
'e'
The middle character is: d
The middle character is: r
The middle character is: a
```

#参考にしたリンク

- [3. Data model](https://docs.python.org/3.3/reference/datamodel.html)
- [What is the difference between \_\_str__ and \_\_repr__ in Python](http://pythoncentral.io/what-is-the-difference-between-__str__-and-__repr__-in-python/)
- [PYTHON REPR AND STR - THE DIFFERENCE](http://satran.in/2012/03/14/python-repr-str.html)
- [Understanding repr() function in Python](http://ask.webatall.com/python/5955_understanding-repr-function-in-python.html)
- [Non-Programmer's Tutorial for Python 3/Revenge of the Strings](https://en.wikibooks.org/wiki/Non-Programmer%27s_Tutorial_for_Python_3/Revenge_of_the_Strings)
- [Evaluating Python Expressions](http://effbot.org/zone/librarybook-core-eval.htm)