The key differences between Python 2.7.x and Python 3.x with examples

多くのPython初心者は、Pythonのどのバージョンから始めるべきか悩んでいます。

しかし、もしあなたが新しいプロジェクトを始めようとしていて、選ぶべき選択肢があるとしたらどうでしょうか? Python 2.7.xとPython 3.xの両方が使用しようとしているライブラリをサポートしていれば、現在のところ「正しい」も「間違っている」もないと言えるでしょう。 しかし、Python の最も人気のある 2 つのバージョン間の主な違いを見ておくことは、どちらかのコードを書くとき、またはプロジェクトを移植しようとしているときに、共通の落とし穴を避けるために価値があります。

セクション

  • セクション
  • __future__ モジュール
  • print 関数
    • Python 2
    • Python 3
  • 整数の割り算。
    • Python 2
    • Python 3
  • Unicode
    • Python 2
    • Python 3
  • xrange
    • Python 2
    • Python 3
    • __contains__

      メソッドの range オブジェクトに対する Python 3 での処理

      • Python 2 と 3 の速度差についての注意点
  • 例外の発生について
    • Python 2
    • Python 3
  • 例外の処理
    • Python 2
    • Python 3
  • Python 2
  • Python 3
  • For-ループ変数とグローバル名前空間のリーク
    • Python 2
    • Python 3
  • 順序付けられない型の比較
    • Python 2
    • Python 3
  • input()によるユーザー入力の解析
    • Python 2
    • Python 3
  • の場合は リストの代わりに反復可能なオブジェクトを返す
    • Python 2
    • Python 3
  • 銀行員の丸め方
    • Python 2
    • Python 3
  • More articles about Python 2 and Python 3
  • The __future__ module

    Python 3.xではPython 2と互換性のないキーワードや機能が導入されており、Python 2では内蔵された__future__モジュールを介してインポートすることができます。 Python 3.x のサポートを計画している場合は、__future__ インポートを使用することをお勧めします。 例えば、Python 3.xの整数除算の動作をPython2で実現したい場合、

    from __future__ import division

    __future__モジュールからインポートできるその他の機能を以下の表に示します。

    feature optional in mandatory in effect
    nested_scopes 2.1.0b1 2.2 PEP 227:Statically Nested Scopes
    generators 2.2.0a1 2.3 PEP 255:Simple Generators
    division 2.2.0a2 3.0 PEP 238:分割演算子の変更
    absolute_import 2.5.0a1 3.0 PEP 328:Imports:
    with_statement 2.5.0a1 2.6 PEP 343:with ステートメント
    print_function 2.6.0a2 3.0 PEP 3105:Make print a function
    unicode_literals 2.6.0a2 3.0 PEP 3112:Bytes literals in Python 3000

    (Source: (https://docs.python.org/2/library/__future__.html#module-__future

    from platform import python_version

    プリント関数

    非常に些細なことです。 そして、print-syntaxの変更はおそらく最も広く知られている変更ですが、それでも言及する価値があります。 Python 2 の print 文は print() 関数に置き換えられました。つまり、印刷したいオブジェクトを括弧で囲む必要があります。

    Python 2 では追加の括弧があっても問題はありませんが、対照的に、Python 3 では、括弧なしで Python 2-way で print 関数を呼び出すと SyntaxError が発生します。

    Python 2

    print 'Python', python_version()print 'Hello, World!'print('Hello, World!')print "text", ; print 'print more text on the same line'
    Python 2.7.6Hello, World!Hello, World!text print more text on the same line

    Python 3

    print('Python', python_version())print('Hello, World!')print("some text,", end="")print(' print more text on the same line')

    となります。

    Python 3.4.1Hello, World!some text, print more text on the same line
    print 'Hello, World!'
     File "<ipython-input-3-139a7c5835bd>", line 1 print 'Hello, World!' ^SyntaxError: invalid syntax

    注意点です。

    上記のPython 2による「Hello, World」の印刷は、ごく「普通」に見えました。 しかし、printはPython2では関数呼び出しではなく「ステートメント」なので、括弧内に複数のオブジェクトがある場合はタプルを作成することになります。

    print 'Python', python_version()print('a', 'b')print 'a', 'b'
    Python 2.7.7('a', 'b')a b

    整数の割り算

    この変更は、コードを移植している場合は特に危険です。 なぜなら、整数分割の動作の変更は、しばしば気づかれないからです (それは SyntaxError を発生させません)。
    だから、私はPython 2の人たちの手間を省くために、Python 3のスクリプトでは3/2float(3)/23/2.0を使う傾向があります(その逆もあります。

    Python 3 のスクリプトでは 3/23/2 を使うようにしています。)

    Python 2

    print 'Python', python_version()print '3 / 2 =', 3 / 2print '3 // 2 =', 3 // 2print '3 / 2.0 =', 3 / 2.0print '3 // 2.0 =', 3 // 2.0
    Python 2.7.63 / 2 = 13 // 2 = 13 / 2.0 = 1.53 // 2.0 = 1.0

    Python 3

    print('Python', python_version())print('3 / 2 =', 3 / 2)print('3 // 2 =', 3 // 2)print('3 / 2.0 =', 3 / 2.0)print('3 // 2.0 =', 3 // 2.0)
    Python 3.4.13 / 2 = 1.53 // 2 = 13 / 2.0 = 1.53 // 2.0 = 1.0

    Unicode

    Python 2ではASCIIのstr()byteタイプはありません。

    さて、Python 3では、ついにUnicode(utf-8)のstrbytebytearraysです。

    Python 2

    print 'Python', python_version()
    Python 2.7.6
    print type(unicode('this is like a python3 str type'))
    <type 'unicode'>
    print type(b'byte type does not exist')
    <type 'str'>
    print 'they are really' + b' the same'
    they are really the same
    print type(bytearray(b'bytearray oddly does exist though'))
    <type 'bytearray'>

    Python 3

    print('Python', python_version())print('strings are now utf-8 \u03BCnico\u0394é!')
    Python 3.4.1strings are now utf-8 μnicoΔé!
    print('Python', python_version(), end="")print(' has', type(b' bytes for storing data'))
    Python 3.4.1 has <class 'bytes'>
    print('and Python', python_version(), end="")print(' also has', type(bytearray(b'bytearrays')))
    and Python 3.4.1 also has <class 'bytearray'>
    'note that we cannot add a string' + b'bytes for data'
    ---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-13-d3e8942ccf81> in <module>()----> 1 'note that we cannot add a string' + b'bytes for data'TypeError: Can't convert 'bytes' object to str implicitly

    xrange

    Python 2.xではxrange()の使い方が非常にポピュラーです。xでは、イテレート可能なオブジェクトを作成するために、例えば。
    その動作はジェネレータに非常に似ていますが、「遅延評価」と呼ばれるものです。 “

    その「遅延評価」のおかげで、通常の range()xrange() が (for-loop などで) 1 回だけ反復しなければならない場合、一般的に高速になることです。) しかし、1回の反復とは対照的に、反復を複数回繰り返す場合は、生成が毎回ゼロから行われるため、お勧めできません!

    Python 3, range()xrange()xrange()関数はもう存在しません(Python 3ではxrange()NameErrorを発生させます)。

    import timeitn = 10000def test_range(n): return for i in range(n): passdef test_xrange(n): for i in xrange(n): pass 

    Python 2

    print 'Python', python_version()print '\ntiming range()'%timeit test_range(n)print '\n\ntiming xrange()'%timeit test_xrange(n)
    Python 2.7.6timing range()1000 loops, best of 3: 433 µs per looptiming xrange()1000 loops, best of 3: 350 µs per loop

    Python 3

    print('Python', python_version())print('\ntiming range()')%timeit test_range(n)
    Python 3.4.1timing range()1000 loops, best of 3: 520 µs per loop
    print(xrange(10))
    ---------------------------------------------------------------------------NameError Traceback (most recent call last)<ipython-input-5-5d8f9b79ea70> in <module>()----> 1 print(xrange(10))NameError: name 'xrange' is not defined

    Python3でのレンジオブジェクトの__contains__メソッド。 in Python 3

    もうひとつ特筆すべきことは、rangeがPython 3で「新しい」__contains__メソッドを得たことです。xになりました(これを指摘してくれたYuchen Yingさんに感謝します)。 この __contains__ メソッドは、Python 3.x の range で、整数型やブール型の「ルックアップ」を大幅に高速化することができます。

    x = 10000000
    def val_in_range(x, val): return val in range(x)
    def val_in_xrange(x, val): return val in xrange(x)

    となります。

    print('Python', python_version())assert(val_in_range(x, x/2) == True)assert(val_in_range(x, x//2) == True)%timeit val_in_range(x, x/2)%timeit val_in_range(x, x//2)
    Python 3.4.11 loops, best of 3: 742 ms per loop1000000 loops, best of 3: 1.19 µs per loop

    上記のtimeitの結果に基づいて。 の結果を見ると、「検索」の実行速度は、floatよりもinteger型の方が約60,000速くなっていることがわかります。 しかし、Python 2.xのrangexrange__contains__メソッドがないので、整数型でも浮動小数点型でも「検索の速さ」はそれほど変わらないでしょう。

    print 'Python', python_version()assert(val_in_xrange(x, x/2.0) == True)assert(val_in_xrange(x, x/2) == True)assert(val_in_range(x, x/2) == True)assert(val_in_range(x, x//2) == True)%timeit val_in_xrange(x, x/2.0)%timeit val_in_xrange(x, x/2)%timeit val_in_range(x, x/2.0)%timeit val_in_range(x, x/2)
    Python 2.7.71 loops, best of 3: 285 ms per loop1 loops, best of 3: 179 ms per loop1 loops, best of 3: 658 ms per loop1 loops, best of 3: 556 ms per loop

    以下に、__contain__メソッドがPython 2.xに追加されていないことを示す「証明」を示します。xにはまだ追加されていません。

    print('Python', python_version())range.__contains__
    Python 3.4.1<slot wrapper '__contains__' of 'range' objects>
    print 'Python', python_version()range.__contains__
    Python 2.7.7---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-7-05327350dafb> in <module>() 1 print 'Python', python_version()----> 2 range.__contains__AttributeError: 'builtin_function_or_method' object has no attribute '__contains__'
    print 'Python', python_version()xrange.__contains__
    Python 2.7.7---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-8-7d1a71bfee8e> in <module>() 1 print 'Python', python_version()----> 2 xrange.__contains__AttributeError: type object 'xrange' has no attribute '__contains__'

    Python2と3の速度差についての注意点

    Python3のrange()とPython2のxrange()の速度差を指摘する声がありました。 これらは同じ方法で実装されているので、同じ速度を期待できるでしょう。 しかし、ここでの違いは、一般的にPython 3はPython 2よりも動作が遅い傾向にあるという事実から来ています。

    def test_while(): i = 0 while i < 20000: i += 1 return
    print('Python', python_version())%timeit test_while()
    Python 3.4.1100 loops, best of 3: 2.68 ms per loop

    div

    print 'Python', python_version()%timeit test_while()
    Python 2.7.61000 loops, best of 3: 1.72 ms per loop

    例外の発生

    Python 2が「古い」と「新しい」の両方の記法を受け入れる場合があります。

    Python 2 が「古い」構文と「新しい」構文の両方の表記を受け入れるところで、Python 3 は例外の引数を括弧で囲まないと詰まってしまいます (そして順番に SyntaxError を発生させます)。

    Python 2

    print 'Python', python_version()
    Python 2.7.6
    raise IOError, "file error"
    ---------------------------------------------------------------------------IOError Traceback (most recent call last)<ipython-input-8-25f049caebb0> in <module>()----> 1 raise IOError, "file error"IOError: file error
    raise IOError("file error")
    ---------------------------------------------------------------------------IOError Traceback (most recent call last)<ipython-input-9-6f1c43f525b2> in <module>()----> 1 raise IOError("file error")IOError: file error

    Python 3

    print('Python', python_version())
    Python 3.4.1
    raise IOError, "file error"
     File "<ipython-input-10-25f049caebb0>", line 1 raise IOError, "file error" ^SyntaxError: invalid syntax

    Python3で例外を発生させるための正しい方法。

    print('Python', python_version())raise IOError("file error")
    Python 3.4.1---------------------------------------------------------------------------OSError Traceback (most recent call last)<ipython-input-11-c350544d15da> in <module>() 1 print('Python', python_version())----> 2 raise IOError("file error")OSError: file error

    例外の処理

    また、Python 3では例外の処理が少し変わりました。 Python 3では、”as“キーワードを使用しなければなりません

    Python 2

    print 'Python', python_version()try: let_us_cause_a_NameErrorexcept NameError, err: print err, '--> our error message'
    Python 2.7.6name 'let_us_cause_a_NameError' is not defined --> our error message

    Python 3

    print('Python', python_version())try: let_us_cause_a_NameErrorexcept NameError as err: print(err, '--> our error message')
    Python 3.4.1name 'let_us_cause_a_NameError' is not defined --> our error message

    div

    next().next())はよく使われる機能(メソッド)ですからね。 これも特筆すべき構文変更(というか実装の変更)です。 Python 2.7.5では、functionとmethodの両方の構文が使えるところ、iv id=

    next()という関数がPython 3では残っているだけです(.next()AttributeErrorが発生します)。

    Python 2

    print 'Python', python_version()my_generator = (letter for letter in 'abcdefg')next(my_generator)my_generator.next()
    Python 2.7.6'b'

    Python 3

    print('Python', python_version())my_generator = (letter for letter in 'abcdefg')next(my_generator)

    Python 3.4.1'a'
    my_generator.next()
    ---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-14-125f388bb61b> in <module>()----> 1 my_generator.next()AttributeError: 'generator' object has no attribute 'next'

    For-ループ変数とグローバル名前空間のリーク

    良いニュースがあります。

    これは Python 3.x で行われた変更に遡り、What’s New In Python 3.0 で以下のように説明されています:

    “List comprehensions no longer support the syntactic form list() コンストラクタ内のジェネレータ式の構文解析に近く、特にループ制御変数が周囲のスコープに漏れなくなっていることにも注意してください。”

    Python 2

    print 'Python', python_version()i = 1print 'before: i =', iprint 'comprehension: ', print 'after: i =', i
    Python 2.7.6before: i = 1comprehension: after: i = 4

    Python 3

    print('Python', python_version())i = 1print('before: i =', i)print('comprehension:', )print('after: i =', i)
    Python 3.4.1before: i = 1comprehension: after: i = 1

    順序付けられない型を比較する

    Python 3のもう一つの良い変更点は、順序付けられない型を比較しようとすると、TypeErrorが警告として表示されることです。

    Python 2

    print 'Python', python_version()print " > 'foo' = ", > 'foo'print "(1, 2) > 'foo' = ", (1, 2) > 'foo'print " > (1, 2) = ", > (1, 2)
    Python 2.7.6 > 'foo' = False(1, 2) > 'foo' = True > (1, 2) = False

    Python 3

    print('Python', python_version())print(" > 'foo' = ", > 'foo')print("(1, 2) > 'foo' = ", (1, 2) > 'foo')print(" > (1, 2) = ", > (1, 2))
    Python 3.4.1---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-16-a9031729f4a0> in <module>() 1 print('Python', python_version())----> 2 print(" > 'foo' = ", > 'foo') 3 print("(1, 2) > 'foo' = ", (1, 2) > 'foo') 4 print(" > (1, 2) = ", > (1, 2))TypeError: unorderable types: list() > str()

    input()によるユーザーの入力を解析する

    残念ながら。 input()関数はPython 3で修正され、ユーザーの入力を常にstrオブジェクトとして保存するようになりました。 Python 2では、stringsraw_input()を使用しなければなりません。

    Python 2

    Python 2.7.6 on darwinType "help", "copyright", "credit" or "license "で詳細を確認できます。>>> my_input = input('enter a number: ')数字を入力してください。 123>>> type(my_input)<type 'int'>>>> my_input = raw_input('enter a number: ')数字を入力してください。 123>>> type(my_input)<type 'str'>

    Python 3

    Python 3.4.1 on darwin "help", "copyright", "credit", "license "を入力すると、より詳しい情報が得られます。>>> my_input = input('enter a number: ')数字を入力してください。 123>>> type(my_input)< class 'str'>

    リストではなく反復可能なオブジェクトを返す

    すでにxrangeのセクションで見たように、いくつかの関数やメソッドは反復可能なオブジェクトを返します。 いくつかの関数やメソッドは、Python 2 のリストではなく、Python 3 では反復可能なオブジェクトを返します。

    通常、これらのオブジェクトは一度だけ繰り返し処理されるので、この変更はメモリを節約するために非常に意味があると思います。

    また、listlist()list に変換するだけです。

    Python 2

    print 'Python', python_version()print range(3)print type(range(3))
    Python 2.7.6<type 'list'>

    Python 3

    print('Python', python_version())print(range(3))print(type(range(3)))print(list(range(3)))
    Python 3.4.1range(0, 3)<class 'range'>

    Python 3ではリストを返さなくなった、よく使われる関数やメソッドをご紹介します。

    • zip()

    • map()

    • filter()

    • dictionary の .keys() メソッド

    • dictionary の .values() メソッド

    • dictionary の .items() メソッド

    Bankerの丸め

    Python 3では、最後の有効数字が同点(…5)になったときに小数を丸めるという、今では標準的な方法を採用しました。5) を採用しました。 現在、Python 3では、小数は最も近い偶数に丸められます。 コードの移植性には不都合がありますが、大きな数字への偏りを避けることができるため、切り上げに比べてより良い丸め方だと思われます。 詳細については、優れた Wikipedia の記事と段落を参照してください。

    • https://en.wikipedia.org/wiki/Rounding#Round_half_to_even
    • https://en.wikipedia.org/wiki/IEEE_floating_point#Roundings_to_nearest

    Python 2

    print 'Python', python_version()
    Python 2.7.12
    round(15.5)
    16.0
    round(16.5)
    17.0

    Python 3

    print('Python', python_version())
    Python 3.5.1
    round(15.5)
    16
    round(16.5)
    16

    More articles about Python 2 and Python 3

    ここでは、Python 2とPython 3に関する記事の中で、フォローアップとしておすすめしたい記事を紹介します。を紹介します。

    //Python 3へのポーティング

    • 自分の開発活動にPython 2とPython 3のどちらを使うべきか

    • What’s New In Python 3.0

    • Python 3への移植

    • Python 2コードのPython 3への移植

    • How keep Python

    //Pro and anti Python 3

    • Python 3へのアップグレードを拒否したために使用できないPythonの10の素晴らしい機能。 なぜなら、あなたは Python 3 へのアップグレードを拒否しているからです

    • Python 3 の Unicode について知りたくなかったことすべて

    • Python 3 は Python を殺している

    • Python 3 は Python を復活させることができる

    • Python 3 は大丈夫

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です