Python2からPython3.0での変更点


# 初めに

この記事は、[Python その2 Advent Calendar 2015](http://qiita.com/advent-calendar/2015/yet_another_python)の9日目の記事です。

## 書こうと思ったわけ

僕がPython初めて書いたのが4年前でとてもよい言語だと思い、簡単なコードなどはいつもPythonで書いていました。
初めに書いたのはPython2.7でしたが、調べていたらPython3なるものがあり、新しいもの好きだったので本気で学ぼうとし始めた時はPython3.3を使ってました。
なので、2系の話などはほとんど知らず、わざわざ古い(といっても当時は2系がメインでしたが)ものを学ぶ必要もないと思ってました。
が。
2系のライブラリが3系に対応していなかったり、2系で書かれていて3系に自分で置き換えなければならないなど色々問題がありました。

とまぁ、とにかく2系と3系の違いを学習ついでにまとめて見ようと思った次第です。
(すでに3系がでてから7年位経っているのは置いといて・・・)
(さらに、他の素晴らしい方々が素晴らしい記事を書いていらっしゃるのも置いといて・・・(T_T))

## 本題に入る前に・・

- 書き始めた際はPython2からPython3.5までの経過を書こうと思ったのですが、Python3.0まででかなりの長さになったのでPython3.0からPython3.5までの経過は別記事に書きます。
- コードを実行したバージョンは左上に書いてあります。
- Pythonの知識がある程度ある方向けになっています。ちょろっと触ったことある方なら多分大丈夫！
- コードの中に突如出てくるアンダーバーは一つ前の実行結果が格納されています。

```pycon:Python3
>>> 1+1
2
>>> _
2
>>> 2+3
5
>>> _ -3
2
>>> type(_)
<class 'int'>
>>> _
<class 'int'>
```

それでは、結構長いですが（笑）
頑張ってきましょう！


# Python2 -> Python3.0

## printが文から関数に変更

```pycon:Python2
>>> print 'Hello'
Hello
```

```pycon:Python3
>>> print('Hello')
Hello
```

Python3での定義はこんな感じらしいです。

```py3
def print(*args, sep=' ', end='\n', file=None)
```

タプルを表示させようとした時とか困るのかな。

```pycon:Python2
>>> print ('item1', 'item2')
('item1', 'item2')
```

```pycon:Python3
>>> print ('item1', 'item2')
item1 item2
>>> print(('item1', 'item2'), )
('item1', 'item2')
```

## リストの代わりにViewsやイテレータを返す

Viewsってナンノコッチャ。
まぁ、結果を見ればわかるでしょう。

### dictのメソッド、keys, items, valuesはViewsを返す

```pycon:Python2
>>> d = {"key1": "value1"}
>>> d.keys()
['key1']
>>> type(_)
<type 'list'>
>>> d.values()
['value1']
>>> d.items()
[('key1', 'value1')]
```

```pycon:Python3
>>> d = {"key1": "value1"}
>>> d.keys()
<dict_keys object at 0x7f0da5268e18>
>>> type(_)
<class 'dict_keys'>
>>> d.values()
<dict_values object at 0x7f0da5268e18>
>>> d.items()
<dict_items object at 0x7f0da3a44638>
```

Python2では全てリストで、Python3では`dict_keys`などのオブジェクトとして返ってきてますね。
これはイテレート可能なオブジェクトで、これをViewsと呼んでいるのでしょう。

Python3でリストとして欲しければ`list()`でラップしましょう。

```pycon:Python3
>>> list(d.keys())
['key1']
```

### dictのメソッド、iterkeys, iteritems, itervaluesの廃止

```pycon:Python2
>>> d.iterkeys()
<dictionary-keyiterator object at 0x7f5b586155d0>
>>> type(_)
<type 'dictionary-keyiterator'>
```

```pycon:Python3
>>> d.iterkeys()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'iterkeys'
```

まー当たり前ですよね。keysがイテレーター返すんですから。

### map, filter関数がイテレーターを返す
```pycon:Python2
>>> f1 = lambda x : x + 1
>>> f2 = lambda x : x%2 == 0
>>> l = [1, 2, 3]
>>> map(f1, l)
[2, 3, 4]
>>> type(_)
<type 'list'>
>>> filter(f2, l)
[2]
>>> type(_)
<type 'list'>
```

```pycon:Python3
>>> iter_check = lambda obj : hasattr(obj, '__iter__') and hasattr(obj, '__next__')
>>> isIterable = lambda obj : hasattr(obj, '__iter__')
>>> f1 = lambda x : x + 1
>>> f2 = lambda x : x%2 == 0
>>> l = [1, 2, 3]
>>> map(f1, l)
<map object at 0x7f0da5261950>
>>> map_obj = _
>>> type(map_obj)
<class 'map'>
>>> iter_check(map_obj)
True
>>>
>>> filter(f2, l)
<filter object at 0x7f0da52619d0>
>>> filter_obj = _
>>> type(filter_obj)
<class 'filter'>
>>> iter_check(filter_obj)
True
```

lambdaの所の内容はあまり気にしなくて大丈夫です（笑）
イテレート可能なオブジェクトなのかイテレーターなのかなどをチェックする関数です。
Python2ではリスト、Python3ではイテレーターが返ってきてますね。


### Python3のrange関数はイテレータオブジェクトを返す(Python2でのxrange)。xrangeは廃止

```pycon:Python2
>>> iter_check = lambda obj : hasattr(obj, '__iter__') and hasattr(obj, '__next__')
>>> isIterable = lambda obj : hasattr(obj, '__iter__')
>>> type(range(1,10))
<type 'list'>
>>> type(xrange(1,10))
<type 'xrange'>
>>> iter_check(xrange(1,10))
False
>>> isIterable(xrange(1,10))
True
```

```pycon:Python3
>>> type(range(1,10))
<class 'range'>
>>> type(iter(range(1,10)))
<class 'range_iterator'>
>>> xrange(1,10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined
```

Python3ではrangeがリストではなくイテレート可能なオブジェクトを返しています。
そしてxrangeはお亡くなりになりました。ﾁｰﾝ

### zip関数はイテレーターを返す
```pycon:Python2
>>> zip([1,2,3], [2,3,4])
[(1, 2), (2, 3), (3, 4)]
>>> type(_)
<type 'list'>
```

```pycon:Python3
>>> zip([1,2,3], [2,3,4])
<zip object at 0x7f0da3a40cf8>
>>> iter_check(_)
True
```
Python3ではイテレーターを返していますね。


## 順序比較
### 比較演算子(<, >, <=, >=)は、そのオペランドが自然な順序付けを持たない場合TypeErrorを送出する
```pycon:Python2
>>> 1 < 'a'
True
>>> 0 > None
True
>>> len <= len
True
>>> None < None
False
```

```pycon:Python3
>>> 1 < 'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>> 0 > None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() > NoneType()
>>> len <= len
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: builtin_function_or_method() <= builtin_function_or_method()
>>> None < None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < NoneType()
```

これ、自分初めて知りました。Python2ひどいですね・・・。
ですがPython3ではしっかり例外を投げてくれるので安心ですね！

### sorted関数とlistのsortメソッドは比較関数を与えるcmp引数を取らなくなった

Python2での定義は以下の通り
`sorted(iterable[, cmp[, key[, reverse]]])`
`s.sort([cmp[, key[, reverse]]])`

Python3での定義は以下の通り
`sorted(iterable[, key][, reverse])`
`sort(*, key=None, reverse=None)`

cmp引数、なくなってますね。
また、Python3でのlistのsortメソッドの引数はキーワード引数で渡す必要があります。

### cmp関数は廃止され、`__cmp__`メソッドはサポートされない
これは例を出すとかではないですよねー。
ソートには`__lt__`メソッドを使用してくれとのことです。


## 整数について
### 基本的にlongはintに改名された(が、古いlong型とほぼ同様に振る舞う)

```pycon:Python2
>>> type(10**100)
<type 'long'>
```

```pycon:Python3
>>> type(10**100)
<class 'int'>
```

Pythonではint型として扱われていますね。

### 1/2のような式はfloatを型を返す。少数点以下切捨て場合は1//2のような式にすること

```pycon:Python2
>>> 1/2
0
>>> type(1/2)
<type 'int'>
```

```pycon:Python3
>>> type(1/2)
<class 'float'>
>>> 1//2
0
>>> type(1//2)
<class 'int'>
```

Python3で除算を行いintで返したい場合は//演算子を使いましょう。

### 整数の上限がなくなったためsys.maxint定数は削除された

```pycon:Python2
>>> sys.maxint
9223372036854775807
```

```pycon:Python3
>>> sys.maxint
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'maxint'
```

削除されてますね。

### long整数のreprメソッドは末尾にLをつけない
```pycon:Python2
>>> 10**20
100000000000000000000L
```

```pycon:Python3
>>> 10**20
100000000000000000000
```

Python3ではLが末尾についていませんね。

### 8進数リテラルが0720のような表記から0o720というような表記に変更

```pycon:Python2
>>> 0720
464
>>> 0o720
464
```

```pycon:Python3
>>> 0720
  File "<stdin>", line 1
    0720
       ^
SyntaxError: invalid token
>>> 0o720
464
```

これは0xや0bなどの表記に統一された形でしょうか。

## ユニコードと8bitの代わりにテキストとデータへ

### 全てのテキストはUnicodeに

タイトル通り。
これによって以前までのユニコードテキストのリテラル`u"..."`は使用できなくなった。

```pycon:Python2
>>> u"unicode"
u'unicode'
```

```pycon:Python3
>>> u"unicode"
  File "<stdin>", line 1
    u"unicode"
             ^
SyntaxError: invalid syntax
```

### テキストはstr型、dataはbytes型

```pycon:Python3
>>> type("test")
<class 'str'>
>>> type(b"test")
<class 'bytes'>
```
バイナリデータのリテラルには`b"..."`を使用する。

### テキストとdataを混ぜるとTypeErrorを送出する

```pycon:Python2
>>> "str" + b"bytes"
'strbytes'
```

```pycon:Python3
>>> "str" + b"bytes"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'bytes' object to str implicitly
```

Python2まじかよ・・（2回目）
こんなの発狂ものですね。。Python3エラい！

### テキストとdata間の明示的変換

```pycon:Python3
>>> "str".encode()
b'str'
>>> bytes("str", "utf-8")
b'str'
>>> 
>>> b"bytes".decode()
'bytes'
>>> str(b"bytes", "utf-8")
'bytes'
```

str, bytes間の変換ですね。
まぁ、Pythonでのencode、decodeの記事は山ほどありますからそちらを参考に・・・。


### raw文字列内でもバックスラッシュはそのままの文字で解釈される

```pycon:Python2
>>> print(ur"\u20ac")
€
```

```pycon:Python3
>>> print(r"\u20ac")
\u20ac
```

Python2まじかよ、とまでは言いませんが、おいっ！
って感じですね。raw文字列のいみねーじゃん！
まぁ、こういう挙動をして欲しい場合もあるかもしれませんがPython3の挙動のほうがいいですよねー。


### basestringという抽象クラスが削除

```pycon:Python2
>>> str.__base__
<type 'basestring'>
>>> bytes.__base__
<type 'basestring'>
```

```pycon:Python3
>>> str.__base__
<class 'object'>
>>> bytes.__base__
<class 'object'>
```

Python2ではbasestringという抽象クラスがあったのですね。それを継承してstr、bytes型ができてたということですね。
Python3では直接それぞれのクラスが定義されていますね。


## 構文の変更の概要

### 関数アノテーションの追加

```pycon:Python3
>>> def f(a: "int_value", b: "int_value default value one" = 1) -> "added_value":
...   return a+b
... 
>>> f.__annotations__
{'a': 'int_value', 'b': 'int_value default value one', 'return': 'added_value'}
```

関数の引数や返り値にアノテーションを追加することができます。
上の例では文字列だけですが、式を書くことができるので、`1+1`や`int`などを書くことができます。

```pycon:Python3
>>> i=2
>>> j=3
>>> def f(a: i*j, b: i+j) -> 1+1:
...  return a+b
... 
>>> f.__annotations__
{'a': 6, 'b': 5, 'return': 2}
>>> i=10
>>> j=10
>>> f.__annotations__
{'a': 6, 'b': 5, 'return': 2}
```

式は関数定義時に評価されます。当たり前っちゃ当たり前ですね。。


### キーワードのみの引数

```pycon:Python3
>>> def f(a, *, b):
...   return a+b
... 
>>> def g(*, a, b):
...   return a*b
... 
>>> f(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 1 positional argument (2 given)
>>> f(1, b=2)
3
>>> g(1, b=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: g() takes exactly 0 non-keyword positional arguments (1 given)
>>> g(a=1, b=2)
2
>>> g(b=1, a=2)
2
```

アスタリスク`*`を使用してそれ以降に列挙される引数をキーワード引数限定とすることができます。
これ日本語の文献すっごく少なくって最初見た時は随分と困りました(笑)

### クラス定義の基底クラスのリストの後にキーワード引数を渡せる

```pycon:Python3
>>> class MClass(type):
...  def __new__(cls, name, bases, namespace, **kwds):
...   result = type.__new__(cls, name, bases, dict(namespace))
...   result.members = tuple(namespace)
...   return result
...  def __init__(self, *args, **kargs):
...   print("args: " + str(args))
...   print("kargs: " + str(kargs))
... 
>>> class A(object, metaclass=MClass, a=1, b=2, c=3):
...   def one(self): pass
... 
args: ('A', (<class 'object'>,), {'__module__': '__main__', 'one': <function one at 0x7f62d071c408>})
kargs: {'a': 1, 'c': 3, 'b': 2}
```

これ、内容が少しヘビーですね・・・。
ともかく基底クラスの後にキーワード引数を受け取ることができます。
ただし、typeではキーワード引数を受け取ることができないので、受け取れるようなmetaclassを自作しなければいけませんが。。(MClassがそれです)

### nonlocal文

```pycon:Python3
>>> def counter(init=0):
...  def cntup():
...   nonlocal init
...   init+=1
...   return init
...  return cntup
...
>>> c = counter()
>>> c()
1
>>> c()
2
>>> c()
3
```

nonlocal文は指定された識別子を一つ上のスコープにある変数を参照できるようにします。
要はクロージャーですかね。
例ではcounter関数の引数initをnonlocal文で参照していますね。
Python2ではlistなどを用いてゴニョゴニョしなければできなかったのですが、Python3では簡潔に書けますね。
(参照するだけであればnonlocalやPython2でのlistなどは必要ない。外側のスコープの変数に束縛を行う際に必要)

```pycon:Python3
>>> c.__closure__
(<cell at 0x7f62d071d5c8: int object at 0x7a3e20>,)
>>> c.__closure__[0].cell_contents
3
```
ついでにこのような形でクロージャーを参照できます。

### 拡張Iterable Unpacking

```pycon:Python3
>>> a, *rest, b = range(5)
>>> a
0
>>> rest
[1, 2, 3]
>>> b
4
```

restにaとbにUnpack後、余ったものをリストとしてUnpackされる。
このrestは空リストとしてUnpackされることもある。

```pycon:Python3
>>> a, *rest, b = range(2)
>>> a
0
>>> rest
[]
>>> b
1
```
これはすごい・・・。


## 変更された構文

### 例外のキャッチの構文

```pycon:Python2
>>> try:
...  raise Exception("test")
... except Exception, e:
...  print "catch exception!"
... 
catch exception!
```

```pycon:Python3
>>> try:
...  raise Exception("test")
... except Exception as e:
...  print("catch exception!")
... 
catch exception!
```

カンマからasキーワードに変更されていますね。


### 新たなraise文のシンタックス

```pycon:Python3
>>> try:
...  raise Exception("test")
... except Exception as e:
...  raise RuntimeError("catch exception!") from e
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: test

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: catch exception!
```

from節が追加され、例外の連鎖を表現できるようになりました。
また、except節で例外が送出された場合も暗黙的に働くそうですよ。

```pycon:Python3
>>> try:
...  1/0
... except Exception as e:
...  raise RuntimeError("raise exception.")
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: raise exception.
```


### True, Falseが予約語に

```pycon:Python2
>>> True = 0
>>> False = 1
>>> True
0
>>> False
1
>>> True and True
0
```

```pycon:Python3
>>> True=0
  File "<stdin>", line 1
SyntaxError: assignment to keyword
>>> False=1
  File "<stdin>", line 1
SyntaxError: assignment to keyword
```

恐怖！！
ってかまぁTrue,Falseに代入したり、普通は！しないですけどね。


### メタクラスのシンタックスの変更

```pycon:Python2
>>> class M(type):
...  pass
... 
>>> class C:
...  __metaclass__ = M
... 
>>> C.__class__
<class '__main__.M'>
```

```pycon:Python3
>>> class M(type):
...  pass
... 
>>> class C(metaclass=M):
...  pass
... 
>>> C.__class__
<class '__main__.M'>
```

Python2では\_\_metaclass\_\_変数、Python3では基底クラスを指定するとこにキーワード引数として渡します。
Python3ではPython2のような手段はサポートしていません。

ここで初めて知ったのが、Python2ではclassでobjectを明示的に継承しないといけなかったのですが、メタクラスを利用することでobjectを継承したクラスができることでした。なるほど！

```pycon:Python2
>>> class A:
...  pass
... 
>>> A.__bases__
()
>>> class C:
...  __metaclass__ = type
... 
>>> C.__bases__
(<type 'object'>,)
```

### ellipsisはどこででも原始的な式として使用できる

```pycon:Python3
>>> ...
Ellipsis
>>> def e():
...  ...
```

省略。(まじで言うことがない・・・)


## 削除された操作

削除されたものなのでさーっといきます。

### タプル引数のアンパック

```pycon:Python2
>>> def foo(a, (b,c)):
...  return a+b+c
... 
>>> t = 2,3
>>> foo(1, t)
6
```

```pycon:Python3
>>> def foo(a, (b,c)):
  File "<stdin>", line 1
    def foo(a, (b,c)):
               ^
SyntaxError: invalid syntax
```

読みづらいですねぇ・・・。
Python3では1行目から怒られます。

### バッククオートについて

```pycon:Python2
>>> i = 123
>>> `i`
'123'
```

```pycon:Python3
>>> i=123
>>> `i`
  File "<stdin>", line 1
    `i`
    ^
SyntaxError: invalid syntax
```

どうやら\_\_repr\_\_メソッドが呼ばれていたようです。

### execについて

```pycon:Python2
>>> exec "print('python2')"
python2
>>> exec("print('python2')")
python2
```

```pycon:Python3
>>> exec "print('python3')"
  File "<stdin>", line 1
    exec "print('python3')"
                          ^
SyntaxError: invalid syntax
>>> exec("print('python3')")
python3
```

Python2ではexec文でした。関数表記も大丈夫です。
Python3では予約語ではなくなり、関数として残りました。

### <>演算子

```pycon:Python2
>>> 1 <> 2
True
>>> 1 <> 1
False
```

```pycon:Python3
>>> 1 <> 2
  File "<stdin>", line 1
    1 <> 2
       ^
SyntaxError: invalid syntax
```

!=でいいじゃないですかねぇ。

### リテラル周り

```pycon:Python2
>>> u"python2"
u'python2'
>>> 100L
100L
```

```pycon:Python3
>>> u"python3"
  File "<stdin>", line 1
    u"python3"
             ^
SyntaxError: invalid syntax
>>> 100L
  File "<stdin>", line 1
    100L
       ^
SyntaxError: invalid syntax
```

上の方で既に述べている内容ですね。

### トップレベル以外でのfrom module import *について

```pycon:Python2
>>> from sys import *
>>> def f():
...  from os import *
... 
<stdin>:1: SyntaxWarning: import * only allowed at module level
```

```pycon:Python3
>>> from sys import *
>>> def f():
...  from os import *
... 
  File "<stdin>", line 1
SyntaxError: import * only allowed at module level
```

WarningからErrorになってますね。なんでPython2はWarningで止めたんだろうか・・・


## その他の変更

### 演算子と特殊メソッド
#### `!=`は`==`と逆の結果を返す(`==`がNotImplementedを返さない場合は)

```pycon:Python2
>>> class C:
...  def __init__(self, a):
...   self.a = a
...
...  def __eq__(self, other):
...   return self.a == other.a
...
>>> a = C(1)
>>> b = C(1)
>>> c = C(2)
>>> a == b
True
>>> a == c
False
>>> a != b
True
>>> a != c
True
```

```pycon:Python3
>>> class C:
...  def __init__(self, a):
...   self.a = a
...
...  def __eq__(self, other):
...   return self.a == other.a
...
>>> a = C(1)
>>> b = C(1)
>>> c = C(2)
>>> a == b
True
>>> a != b
False
>>> a == c
False
>>> a != c
True
```

これちょっと意外でした。
Python2の`!=`は`__ne__()`を実装していないのでオブジェクトが同一のものかを比較しています。
a, b, cはどれも別物なので結果がTrueになっています。
自分はてっきりAttributeErrorが出るのかと思ってました・・・。少し考えれば分かる話でしたね。

#### unbound methodsからfunction objectへ
```pycon:Python2
>>> class C:
...  def f(self):
...   pass
...
>>> C.f
<unbound method C.f>
```

```pycon:Python3
>>> class C:
...  def f(self):
...   pass
...
>>> C.f
<function f at 0x100a35270>
```

はい。Python3がただの関数として扱われています。
unbound methodはインスタンスに紐付いていないメソッドということでしょう。
Python3のほうが単純明快で分かりやすいですね

#### `__getslice__()`系のメソッドは削除され、`__getitem__()`系のメソッドにsliceオブジェクトが渡される

```pycon:Python2
>>> class C:
...  def __getslice__(self, i, j):
...   print i, j
...   raise NotImplementedError()
...
>>> a = C()
>>> a[0:2]
0 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __getslice__
NotImplementedError
```

```pycon:Python3
>>> class C:
...  def __getitem__(self, obj):
...   print(obj)
...   print(type(obj))
...   raise NotImplementedError()
...
>>> a = C()
>>> a[0:2]
slice(0, 2, None)
<class 'slice'>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __getitem__
NotImplementedError
```

- __getslice__
- __setslice__
- __delslice__

が

- __getitem__
- __setitem__
- __delitem__

を代わりに呼ぶようになり、スライスオブジェクトが渡されるように変わりました。
例では実装をしていませんが、引数にスライスオブジェクトが渡されているのがわかりますね。

#### `next()`メソッドは`__next__()`に改名された

```pycon:Python2
>>> class C:
...  def __iter__(self):
...   return self
...
...  def next(self):
...   return 0
...
>>> a = C()
>>> i = iter(a)
>>> next(i)
0
>>> i.next()
0
```

```pycon:Python3
>>> class C:
...  def __iter__(self):
...   return self
...
...  def __next__(self):
...   return 0
...
>>> a = C()
>>> i = iter(a)
>>> next(a)
0
>>> i.__next__()
0
```

`next()`から`__next__()`が呼ばれるように変わっていますね。

#### `__oct__()`と`__hex__()`は削除され、`__index__()`を使用すること

```pycon:Python2
>>> class C:
...  def __oct__(self):
...   return "07"
...
...  def __hex__(self):
...   return "0x7"
...
>>> a = C()
>>> hex(a)
'0x7'
>>> oct(a)
'07'
```

```pycon:Python3
>>> class C:
...  def __index__(self):
...   return 7
...
>>> a = C()
>>> hex(a)
'0x7'
>>> oct(a)
'0o7'
```

`__oct__()`、`__hex__()`は数値を文字列に変換して返すメソッドなのですが、`__index__()`は数値を返すだけです。後はPythonが良しなに変換してくれます。
Python3素晴らしい〜。
(例は定数返してますがご勘弁を・・・)

#### `__nonzero__()`は`__bool__()`に改名された

```pycon:Python2
>>> class C:
...  def __nonzero__(self):
...   return True
...
>>> a = C()
>>> bool(a)
True
```

```pycon:Python3
>>> class C:
...  def __bool__(self):
...   return True
...
>>> a = C()
>>> bool(a)
True
```

`__nonzero__()`ってどういう流れで名前が決まったんですかね・・・。
Python3では`__bool__()`が呼ばれています。分かりやすい。

### Builtins

#### `super()`の追加

```pycon:Python3
>>> class SuperClass:
...  pass
... 
>>> class SubClass(SuperClass):
...  def findSuperClass(self):
...   print("call super(): ", super())
...   print("call super(SubClass, self)", super(SubClass, self))
...
>>> i = SubClass()
>>> i.findSuperClass()
call super():  <super: <class 'SubClass'>, <SubClass object>>
call super(SubClass, self) <super: <class 'SubClass'>, <SubClass object>>
```

`super()`は引数無しで呼び出すことができ、適切なクラスとインスタンスを自動的に選んでくれます。
引数がある時と処理は特には変わりません。

#### `raw_input()`が`input()`に改名

```pycon:Python3
>>> input()
test
'test'
```

`input()`は標準入力から1行読み取り、改行を除いた文字列を返します。
Python2での`input()`を実行したい場合は`eval(input())`で実現できます。


# まとめ
ぶっちゃけPython3では

- printが関数に
- keys, items, valuesメソッドはイテレート可能なオブジェクトを返す
- 文字列の標準がUnicodeになり型が`str`
- xrangeがrangeに

辺りを覚えておけば殆ど支障はないと思います。

また、この記事で省いた変更点がいくつかあるのですが、ニッチな内容であまり重要でない気がしたものを全体の1割ほど削っています。知りたい方は[What's New in Python3.0](https://docs.python.org/3/whatsnew/3.0.html)読んでください(丸投げ)。

# 終わりに

記事を書いてて思ったことですが、Python2で罠にハマりそうな点がいくつかあってびっくりしました。
自分でやり始めたのがPython3からで良かったです（笑）

そしてまだPython2から乗り換えてない方は便利にこれを機会に覚えていただいてPython3に乗り換えると幸せなPythonライフが待っているのではないでしょうか(笑)
(Python2から3とかもう随分たっててまとめ系の記事は沢山ありますが・・・)

冒頭でも書きましたが、Python3.0からPython3.5までの経過は別記事で書こうと思います。
Python3.0からPython3.5までの経過はPython その2 Advent Calendar の16日にのせるつもりです。

また、変な点や間違い、こうした方が良いなどありましたらコメントくださるとありがたいです！

明日は空きで、11日は@FGtatsuroです！

**それでは良きPython3ライフを！！**