はじめに†
本文はGuido van Rossumの"What's New In Python 3.0"( http://docs.python.org/3.0/whatsnew/3.0.html )の全訳です。翻訳のルール等については、下記の「翻訳についてのおことわり」を参照してください。
- Python 3.0 の新機能
- 著者:Guido van Rossum
- 日付:2009年1月4日
この記事は、Python 2.6と比較したPython 3.0の新機能について説明します。『Python 3000』および『Py3k』としても知られているPython 3.0は、『後方互換を意図的に除いた』Pythonの初めてのリリースです。通常のリリースにあるよりもたくさんの変更があり、またそのような変更はすべてのPythonユーザーにとって重要なものです。にもかかわらず、変更を整理した後、実際にはPythonには大きな変更がなかったと気づくでしょう。そして私達は、主に有名な厄介事と醜いものを修正していて、たくさんの古い嫌なもの(cruft)を削除しています。
この記事では、すべての新機能の完全な仕様を説明するつもりはありませんが、代わりに便利な概観を提示します。詳細については、Python 3.0のドキュメント、あるいはそこで参照されている多くのPEPを参照してください。あなたが、完全な実装と特定の機能のための設計原理を理解したいならば、PEPは通常のドキュメントより多くの詳細な情報を持っています。ただし機能が完全に実装されたら、PEPは通常アップデートされないことに注意してください。
(訳注:
PEP = Python Enhancement Proposal( http://www.python.org/dev/peps/ )
Pythonの仕様変更の提案及び進行状況の報告の場。Pythonistaであれば知らなければモグリだが、他言語がメインのユーザの中にはご存じ無い方がいるかも知らないので蛇足を承知で念のため。ちなみに、ここで提案されても通らなかったり、変更されたりするものもある)
時間的制約のため、この文書は(かくあるべきとされるほど)完全ではありません。いつものように新しいリリースでは、ソースの配布物の中の『Misc/NEWS』のファイルに、変更の仔細の全てに関する詳細な情報が満載されています。
共通の障害†
このセクションでは、Python 2.5を使用しているほとんどの人がつまづくであろう、幾つかの変更点がリストアップされています。
『print』は関数に†
古いprint文の特殊な文法は廃止され、print関数(とキーワード引数)に置き換えられました。例:
| 旧: | print "The answer is" , 2 * 2 |
新: | print ( "The answer is" , 2 * 2 ) |
| 旧: | print x , # 末尾のコンマが改行を抑制 |
新: | print ( x , end = " " ) # 改行の代わりにスペースを付加 |
| 旧: | print # 改行を出力 |
新: | print() # 『print関数』を呼び出す必要があります |
| 旧: | print >> sys.stderr , "fatal error" |
新: | print("fatal error", file = sys.stderr) |
| 旧: | print(x , y) # repr( (x, y) )を出力 |
新: | print ( ( x , y ) ) # print(x, y)とは別! |
アイテムとアイテムの間のセパレータをカスタマイズすることもできます
例えば……
print("There are <", 2 ** 32, "> possibilities!", sep = "")
は、
There are <4294967296> possibilities!
を生成します。
注記:
- print関数は、古いprint文の『softspace』をサポートしていません。 (訳注:softspace:行頭のスペースを制御して、行頭のスペースを抑制する機能)例えばPython 2.xでは、『print "A¥n", "B"』は『"A¥nB¥n"』を出力しましたが、Python 3.0で
は『print("A¥n", "B")』は『"A¥n B¥n"』を出力します。
- 最初あなたは、インタラクティブモードで何度も『print x』と打ってしまう(ことに気づく)でしょう。(しかし)時間が、あなたの指を(かわりに)『print(x)』(と打てるよう)に再教育するでしょう。
- 2→3コード変換ツールを使うと、全print文が自動的にprint関数呼び出しに変換されます。よってこれは大部分の大きなプロジェクトにとって殆ど問題ではありません。
(訳注:
『2→3コード変換ツール』[原文:2to3 source-to-source conversion tool, 2to3 tool, 2to3 source-to-source translator, 2to3 translatorなど]
Python 2.xのソースコードをPython 3.0準拠に変換してくれるツール。Python 3.0移行の切り札的存在。ただし後述のように、その場合は先になるべく2.6準拠のコードに直しておかないとあまりうまく働かない)
リスト(list)の代りのビュー(view)とイテレータ(iterator)†
いくつかのよく知られているAPIは、もはやリストを返しません。
- 辞書(dict)のメソッドのdict.keys, dict.items, dict.valuesは、リストの代りにビュー(view)を返します。例えば、こういった使い方はもはやできません『k = d.keys(); k.sort()』。代わりに、『sorted(d)』を使用します(これはPython 2.5でも動作し、能率よく機能します)
- また、dict.iterkeysメソッドとdict.iteritemsメソッドとdict.itervaluesメソッドは、もはやサポートされません。
- map関数とfilter関数は、イテレータ(iterator)を返します。もしあなたが本当にリストが必要なら、一番手っ取り早い方法はlist(map(...))などと修正することです(訳注:list(map(...))とすると、戻り値としてリストが得られます)が、一般的により良い修正は、(特に元のコードでlambdaが使用されているのなら)しばしばリストの内包記法を用いることです。あるいはリストが必要無いようにコードを書き直すことです。特に呼び出した関数に副作用を引き起こすmap関数の使用は、邪道です。正しい変換は、普通のループを使用することです(どうせリストを作成するだけ無駄でしょうから)
- range関数は、任意のサイズの値で動作する以外は、xrange関数のように振舞うようになりました。後者(xrange関数)は、もはや存在していません。
- zip関数はイテレータを返します。
順序の比較†
Python 3.0では順序の比較のルールを簡略化しています。
- 順序比較演算子(<, <=, >=, >)は、比較するものに意味のある自然な順序が無い時、『TypeError例外』を発生させます。したがって、『1 < ''』『0 > None』あるいは『len <= len』といった(比較は)もはや妥当ではありません。たとえば『None > None』の場合、『False(否)』を返すのではなく『TypeError例外』を発生させます。結果、異種オブジェクト間のソーティングはもはや意味はありません。全ての要素が互いに比較可能である必要があります。注意:これらの新しいルールは、(同一性テストにも用いる)『==』や『!=』には適用されません。比較できない異なる型のオブジェクトは、常に互いに『同一ではない』と判定されます。
- sorted組み込み関数とlist.sortメソッドは、もはや『cmp』を引数に取ることはできません。代わりに『key』という名称のキーワード引数に(比較関数を)渡します。注意:『key』と『reverse』引数は、今や『keyword-only』です。(訳注:sorted(list, reverse=True)とすると、逆順にソートできます(reverse=1でも可))
- cmp関数は無くなったものとみなしましょう。そして__cmp__特殊メソッドはもはやサポートされません。ソーティング(整列)には__lt__メソッド、__eq__メソッド、__hash__メソッド、および必要に応じてその他の豊富な比較方法が用いられます(もし本当にcmp関数の機能が必要なら、"(a > b)-(a < b)"をcmp(a, b)と等価のものとして用いることができます)
(訳注:True - False ⇒ 1, False - True ⇒ -1)
- [PEP 0237] longという名称だったものが int に改称され、Pythonにある整数型は int ただ一つになりました。名前こそintですが旧来のlongとほぼ同様に動作します。
- [PEP 0238] 『1 / 2』のような式は、浮動小数点数(float)を返します。切捨ての(動作を行った)結果を得るには、『1 // 2』を使用します。(後者の構文は、何年も前から……少なくともPython 2.2の年から……存在しています)
- sys.maxint定数は削除され、もはや整数値に上限はありません。しかしながらsys.maxsize定数は、実際のリストや文字列の(最大)インデックスよりも大きい数値です。(訳注:リストや文字列のインデックスは、sys.maxsizeを越えられません)これは、実装の『自然な』整数のサイズに適合します。そしてこれは、一般的に以前のリリースの同じプラットフォームのsys.maxintと同じです(なお、当然同一オプションでビルドされたものとします)
- 『ロング整数』のreprでは、後ろに'L'をつけません。従って、無条件に、そのキャラクタを取り除くコードは代わりに最終桁を切り落としてしまうでしょう。
(訳注:reprはrepr関数での出力を意味するとともに、オブジェクトの文字表現を意味する。repr = representation)
- 八進法のリテラルは、『0720』ではなく『0o720』と書きます。
『Unicode 対 8ビット』の代わりに『テキスト 対 データ』を†
バイナリデータとUnicodeについて、あなたが知っている全てのことは変わってしまいました。
- Python 3.0では、『テキストと(バイナリ)データ』の概念を、『Unicode文字列と8ビット文字列』の代わりに採用しています。すべてのテキストはUnicodeです。しかしながら、エンコードされたUnicodeはバイナリデータとして表現されます。(訳注:PythonはUnicodeをUTF-8の形で扱う)テキストを保持するために使用するのは『str』型です。そしてデータを保持するために使用するのは『bytes』型です。2.xの場合との最大の違いは、テキストとデータの如何なる混同の試みでも、Python 3.0ではTypeErrorを発生させるということでしょう。Python 2.xでは、Unicodeと8bitの文字列を混合したとき、(Unicode文字列が)偶然7ビット(ASCII)bytsだけのバイト列であったならば、それは動作したでしょう。しかし、(Unicode文字列が)非ASCII値を含んでいたならば、UnicodeDecodeErrorを見ることになったでしょう。この値依存の現象は、長年数多くの悲劇を生んできました。
- この設計思想の変更の結果、ほぼ全てのUnicode、エンコーディング、またはバイナリデータを扱うコードが変更されなければならないでしょう。この変更のほうがマシなのは、2.xの世界ではエンコードされたテキストとエンコードされていないテキストを混ぜて扱わなければならなかったことに起因したバグが、大量にあったたです。(3.x移行に備えて)2.xで準備しておくべきことは、
エンコードされていない全てのテキストで『unicode』型を使い始めることと、『str』型はバイナリデータか、エンコードされたデータのみで使うことでしょう。そうしておけば、(あとは)2→3コード変換ツールが作業をほとんどやってくれます。
- あなたはもはや、 Unicodeテキストには『u"..."』リテラルを使用することはできません。しかしながら、バイナリデータには『b"..."』リテラルを使わなければなりません。
- str型とbytes型が混同不可能なため、いつでも明示的に相互に変換する必要があります。str.encodeメソッドを使えば、str型からbytes型に変換します。そしてbytes.decodeメソッドは、bytes型からstr型に変換します。また、それぞれ
bytes(s, encoding=...)
や
str(b, encoding=...)
を使うこともできます。
- str型と同様に、bytes型も不変型です。バッファされたバイナリデータを扱うための、1バイトづつ切り離して別々に扱う可変型として、bytearray型があります。bytes型オブジェクトを受け入れるAPIは、ほぼ全てbytearray型オブジェクトを受け入れます。可変型に対応するAPIは、collections.MutableSequenceに基づいています。
- raw文字列リテラル内のすべてのバックスラッシュは、文字通りに解釈されます。つまり'¥U'と'¥u'も、raw文字列の中では特別扱いされません。(訳注1:バックスラッシュとはコード0x5Cのキャラクターで、日本語環境下では半角の¥文字として表示されることが多い)(訳注2:単独の『¥』は行の継続を意味する記号となるので、r'¥'とは書けないため、実は『¥』単体だけはraw文字列で表記することは不可能。『¥』単体は通常のstrで'¥¥'か'¥x5c'を用いる)例えば、Python 2.6ではur'¥u20ac'は1文字の『ユーロ記号(Cに=のアレ)』であるのに対して、r'¥u20ac'はPython 3.0では(文字どおり)6文字(扱い)です。(もちろん、この変更はraw文字列だけに影響を与えます。『ユーロ記号』文字列は、Python 3.0でも'¥u20ac'で表せます)
- 組み込みのbasestring抽象型は削除されました。かわりにstr型を使用してください。(訳注:basestring型は、2.xでは8bit専用だったstr型とUnicode文字列を統合的に扱うために存在した)str型とbytes型は、基底クラスを共有するほどの共通機能を持っていません。2→3コード変換ツール(下記参照)は、basestring型の全ての出現をstr型に置き換えます。
- ファイルをテキストファイルとして開く(open関数のデフォルトのモード)時は常に、文字列(メモリ上)とバイト列(ディスク上)の間の対応のためにエンコーディングを行います。バイナリファイル(『b』モード引数を使用して開いた)は常にメモリ内のバイト列を使用します。つまり、もし、ファイルを開く時に不正なモードまたはエンコーディングが使用されると、I/Oは静かに不正なデータを作るかわりに、おそらく派手に失敗します。また、 Unixのユーザでさえも平等に、(テキストまたはバイナリ)のファイルを開くときには、正しいモードを指定する必要があることを意味します。プラットフォーム依存のデフォルトのエンコーディングがありますが、UNIX型プラットフォームに於いては、LANG環境変数(そして時には、いくつかの他のプラットフォーム固有のロケールに関連する環境変数)をセットすることができます。多くの場合システムのデフォルトはUTF-8です……が……しかし、『全て』ではないので、デフォルトがUTF-8であることを当てにしないでください。純粋なASCIIの範囲を超えたテキストを読み書きするすべてのアプリケーションはエンコーディングを上書きする手段を持たせるべきでしょう。もはやコーデックモジュールでエンコーディングを承知しているストリームを扱う必要はありません。
- ファイル名はAPIから(Unicode)文字列として通って、返されます。これは現在、プラットフォーム固有の問題を生んでいます。なぜなら、いくつかのプラットフォームのファイル名は任意のバイト文字列だからです。(その一方で、Windowsのファイル名はネイティブのUnicodeとして格納されます)回避策としては、殆どのAPI(例えば、open関数やosモジュールの数多くの関数など)は、ファイル名を文字列よりバイト列オブジェクトで受け取ります。そして幾つかのAPIでは、バイト列を戻り値として求める方法があります。例えば、os.listdir関数は、もし、引数がbytes型ならば、バイト列のリストを返します。そしてos.getcwdb関数は、現在の作業ディレクトリをバイト列で返します。os.listdir関数が文字列のリストを戻す時に、適切にデコードされることができないファイル名は、UnicodeError例外をraiseしないでエラーを無視します。
- システムによって使用可能にされたバイト列が、デフォルトのエンコーディングを使って、解釈可能でない時、os.environとsys.argvのような幾つかのシステムAPIは、問題をおこす可能性があります。LANG変数を設定し、プログラムを再実行することが、たぶん最もよいアプローチでしょう。
- [PEP 3138] 文字列のreprは、もはや非ASCII文字をエスケープしたりしません。しかしながら、ユニコード標準の中で印刷可能でないステータスを持つコードポイントと制御文字は、エスケープされることになります。
- [PEP 3120] ソースコードで使われるデフォルトのエンコーディングはUTF-8となりました。
- [PEP 3131] 非ASCII文字でも識別子として使えます(ただし、標準ライブラリでは、コメント欄の寄稿者の名前を除き、ASCIIのみが許可されています )
- StringIOとcStringIOモジュールはなくなりました。代わりに、ioモジュールをインポートして、io.StrintIOやio.BytesIOを、テキストとデータにそれぞれ使用します。
- 詳しくは、Python 3.0で更新された『the Unicode HOWTO』を参照してください。
構文の変更点の概要†
このセクションではPython 3.0のすべての構文の変化の概要を説明します。
新しい構文†
- [PEP 3107] 関数の引数と戻り値の注釈。これは、関数のパラメータや戻り値の注釈に、標準化された方法を提供します。この注釈をつけることは、__annotations__属性を実行時に内省(自己分析)するのに使用する、などの用途を除き、(機能的には)何の意味も付与しません。その意図は、メタクラス、デコレータ(修飾子)、またはフレームワークを通して実験を奨励することです。
- [PEP 3102] keyword-only』引数。パラメータリストの*argsの後に置かれる名前つきのパラメータは、呼び出す時にキーワード構文を使って指定されます。(訳注:*argという書式は、それ以降の(特にキーワード指定のない)パラメータをリストとして受け取ります。これ以降の仮引数は、キーワードで指定されない限り、その仮引数に引き渡されません)関数で可変長引数リストを受け取らないことを示すために、パラメータリストの中で裸の‘*’を使うことができます。ただし、その場合、『keyword-only』引数を設定する必要があります。
- キーワード引数が、クラス定義の基底クラスのリストの後に使えるようになりました。これは、メタクラスを指定するための新しい規定によって使われます(次節参照)。ただし、メタクラスがこれをサポートするかぎり、これは他の目的にも同様に使えます。
- [PEP 3104] nonlocal文。'nonlocal x'を使うと、あなたは直接外側スコープの変数に代入することができます(でもxはglobalではありません)。'nonlocal'は新しい予約語です。
- [PEP 3132] 反復可能オブジェクトの展開書式の拡張。『a, b, *rest = some_sequence』のような書きかたが可能になりました。さらに『*rest, a = stuff』のような書きかたも。『rest』オブジェクトは常に(ひょっとしたら空の)リストであり、右側は反復可能な(オブジェクト)であれば何でもかまいません。例:
(a, *rest, b) = range(5)
この書式では、aに0を、bには4を、そしてrestに [1, 2, 3] をセットします。
- 辞書の内包表記『{k: v for k, v in stuff}』は、『dict(stuff)』と同等です。しかし、もっと柔軟です(これはPEP 0274を擁護しています :-)
(訳注:stuffは『要素』なので、
( (1,100),(2,200) )
のようなkey-value対応のモノを想定している。しかし、たとえばdが辞書ならば、
x = dict(d)
は通っても
x = {k: v for k, v in d}
は通らない。この場合、
x = {k: v for k, v in d.items()}
とする必要がある)
- {1, 2}のような集合リテラル。注意:{}は空の辞書のリテラルです。空の集合には、『set()』を使ってください。集合の内包記法もサポートされています。
例:
{x for x in stuff}
は
set(stuff)
と同等ですが、より柔軟です
- 新しい8進数のリテラルは、『0o720』のように書きます(2.6でも既に使えます)。これまでの8進数のリテラル『0720』はなくなっています。(訳注:以前のPythonでは、先頭に0がくる整数は8進法表記となっていた)
- 『0b1010』のような新しい二進法リテラル、(2.6でも既に使えます)は新しい組み込み関数であるbin関数に対応します。
- byte列のリテラルは'b'か'B'を先頭につけます。そして新しい対応する組み込み関数は、bytes関数です。 (訳注:バイト列のリテラルはb'¥x01¥x02'やb'abc'のように書きます)
変更された構文†
- [PEP 3109]と[PEP 3134] 新しいraise文の構文『raise [expr [from expr]]』。下記参照してください。
- 『as』と『with』が新しく予約語になりました(実際は2.6から)『True』と『False』及び『None』は予約語です(2.6では部分的に『None』に関する制限の強制を行っています)
- 『except exec, var』が『except exc as var』という書きかたに変更されました。PEP 3110参照のこと。
- [PEP 3115] 新メタクラス構文。
class C:
__metaclass__ = M
...
の代りに、
class C (metaclass = M):
... ...
を使って下さい。モジュール全体で使える__metaclass__変数は、もはやサポートされていません。 (__metaclass__変数は、『object』からすべてのクラスを派生させずに、新スタイルのクラスを容易にデフォルトにするための補助でした)
- リスト内包記法はもはや
[... for var in item1 , item2 , ...]
という書きかたをサポートしていません。代わりに
[... for var in ( item1 , item2 , ...)]
を使用してください。また、リストの内包表現は別の意味を持つことに気をつけてください。(リストの内包表現は)リストのコンストラクタの内部で式を生成するための構文糖衣のようなものです。特に、ループの制御変数はループを囲むスコープに漏れないようになりました。
(訳注:2.xに於けるリストの内包記法で用いられる変数(例えば『[x for x in range(10)]のx』は、リストの外にも影響を与えていた。しかしジェネレータ式はローカル変数として扱われていた。そのため、外部の変数に影響を与えないため、次のような裏技が用いられていた。
《Python 2.x》
>>> x = 100
>>> [x for x in range(10)] # リストの内包記法
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
9 ←変数xの内容が変更されている
>>> x = 100
>>> (x for x in range(10)) # ジェネレータの内包記法
<generator object at 0x4031362c>
>>> x
100 ←変数xの内容が変更されていない
>>> list(x for x in range(10)) # ジェネレータの内包記法とlist関数(listクラスのコンストラクタ)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
100 ←変数xの内容が変更されていない
しかし、Python 3.0ではリスト内包記法の変数もローカルとして扱われるため、上記のような小手先の技は必要なくなった
《Python 3.0》
>>> x = 100
>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
100
>>>
)
- 省略記号『...』(三連のピリオド)は、字句要素としてどこでも使うことができます(『...』はこれまでスライスの中でのみ許されていました)そのかわり『...』と記述しなければなりません(以前は単なる文法上のアクシデントによって『. . .』 (間に空白が入っている) という記述も許されていました)
削除された構文†
- [PEP 3113] 『タプルパラメータの展開』を削除。
def foo(a, (b, c)):
...
……という書きかたは、もはや使えません。代わりに
def foo(a, b_c):
b, c = b_c
などとして下さい
- バックティック(backticks)は削除されました(代わりにrepr関数を使用してください)(訳注:バッククォート『`』による評価のこと。『`expr`』は『repr(expr)』の略記として使えたが、3.0から使えなくなった)
- 『<>』は削除されました。代わりに『!=』を使用してください
- 予約語の削除。『exec』はもうすでに予約語ではなく、exec関数として残っています。(幸いにも、この関数構文は既に2.xで取り入れられています)さらに注意すべきは、exec関数はもうすでにストリーム(引数)には使えません。exec(f)とする代わりに、exec(f.read())を利用してください。
(訳注:原文では『キーワード(keyword)』と書かれているが、『予約語(reserved word)』の誤りと思われる。Pythonでは、キーワードは、引数などを指定する名前(キーワード引数)などに使われ、他の言語のように予約語の意味として使われることはほとんどない)
- 整数リテラルでは、もはや末尾の'l'または'L'はサポートされません。(訳注:前述の通り、ロング整数型は整数型に統合された)
- 文字列リテラルでは、もはや『u'...'』や『U'...'』はサポートされません。(訳注:前述の通り、Unicode文字列はstrに統合された)
- 『from module import *』構文は、モジュールレベルのみ許可されます。もはや関数の中では使えません。
- 相対importとして許されるのは、『from .[module] import name』だけです。(訳注:相対import(rerative import)は、モジュール階層を辿ってインポートするための構文)『.』から始まらない全てのimportは、絶対importとして解釈されます。(PEP 0328)
Python 2.6 において既に提示された変更†
おそらく多くのユーザーはPython 2.5 から Python 3.0 へ直接移行するでしょうから、このセクションは新しい機能は元々 Python 3.0のために設計されたものでPython 2.6 に逆移植されたものだと読者に思い出させることになるでしょう。『What’s New in Python 2.6』の中の対応するセクションには、より詳細な説明があります。
- [PEP 343] with文。__future__からimportすることなく通常の機能としてwith 文が使えるようになりました。また、『Writing Context Managers』と『contextlib』モジュールについてもチェックしてみてください。
- [PEP 366] メインモジュールからの明示的な相対import。これは、パッケージの中に参照モジュールが存在している場合、 -mオプションの有用性を高めます。
- [PEP 370] ユーザーごとのsiteパッケージのディレクトリ。
- [PEP 371] マルチプロセッシングパッケージ
- [PEP 3101] 拡張された文字列フォーマット。注意:2.6版の解説は、8ビットとUnicodeの文字列の両方のためのformat()メソッドに言及しています。3.0では、このメソッドはstr型(Unicodeによるテキスト文字列)のみをサポートします。bytes型はサポートしません。このAPIを文字列をフォーマットするための唯一のものとすることが計画されていて、Python 3.1 からは % 演算子が非推奨のものとなります。
- [PEP 3105] print文は関数のように(扱ってください)このやり方は標準のものとなったので、__future__をimportする必要はなくなりました。詳細はすでに上記で説明済みです。
- [PEP 3110] 例外処理の変更。『except exc as var』構文は、今や標準になりました。『except exc, var』構文はすでにサポートされていません。(もちろん、『as var』の部分は省略可能です)
- [PEP 3112] バイト列リテラル。『b"..."』文字列リテラル表記(そして、b'...',b"""...""",あるいはbr"..."のようなバリエーションの表記)は、今やbytes型オブジェクトを生み出すリテラルです。
- [PEP 3116] 新しいI/Oライブラリ。ioモジュールはファイル入出力を行うための新しい標準的な方法となりました。これとあわせて sys.stdin , sys.stdout and sys.stderrの初期値は io.TextIOBase のインスタンスになっています。組み込みのopen関数は、今やio.openのエイリアスであり、encoding、errors、newline、closefdなどのキーワード引数が追加されました。また、無効なモード引数は、今やIOErrorではなくValueErrorを発生させます。テキストファイルオブジェクトを基礎とするバイナリファイルオブジェクトは、『f.buffer』としてアクセスできます(ただし、テキストオブジェクトがエンコードやデコードの操作を高速化するために自身のバッファを保持していることに注意してください)。
- [PEP 3118] 改訂された、バッファのプロトコル。古いbuffer関数は、今や本当になくなりました。新しい組み込み関数のmemoryview関数は、(ほとんど)同じような機能を提供します。
- [PEP 3119] 抽象基底クラス。abc モジュールと、collections モジュールで定義されていた抽象基底クラス群 (ABC)は、今や言語にとってもっと顕著な役割を果たします。そして、dictやlistのようなコレクション型は、それぞれcollections.MutableMappingやcollections.MutableSequenceの抽象基底クラスに準拠します。
- [PEP 3127] 整数リテラルのサポートと構文。上述した通り、8進数は新しいリテラル表記だけがサポートされます。そしてバイナリリテラルが追加されています。
- [PEP 3129] クラスデコレータ(修飾子)
- [PEP 3141] 数値の型階層。numbers モジュールはもう一つの新しい抽象基底クラスの使用で、Python の "numeric tower" を定義しているものです。また、numbers.Rationalを実装した新しいfractionsモジュール(分数モジュール)にも注意してください。
ライブラリの変更†
時間の制約のため、この文書は標準のライブラリの、あまりにも広範囲な変更を、徹底的にカバーしているわけではありません。PEP 3108は、ライブラリの比較的大きな変更の、リファレンスです。
- 多くの古いモジュールが削除されました。 (たとえば)いくつかの、(すでに使われていなかった)gopherlibモジュールや、(hashlibに置き換えられた)md5モジュールなどは、すでにPEP 0004において非推奨となっていました。その他には、IrixやBeOS、そしてMac OS9などの様々なプラットフォームがサポートを打ち切られた結果として削除されたものもあります(PEP 0011参照)。あるモジュール群は、使用されないために、あるいはより良い代替存在するために、Python 3.0で削除されることが選択されました。
- bsddb3パッケージは、コアの標準ライブラリの中のその存在が、テストの不安定と、バークレイDBのリリーススケジュールによるコア開発者のための特定の負担であると、時間とともに判明したので、削除されました。しかしながら、そのパッケージはまだ存在しています。そして、立派に外部(http://www.jcea.es/programacion/pybsddb.htm)で維持管理されています
- あるモジュール群は改称されました。なぜなら古い名前はPEP 0008の規則に反しているから、など様々な理由からです。
旧名称 | ⇒ | 新名称 |
_winreg | ⇒ | winreg |
ConfigParser | ⇒ | configparser |
copy_reg | ⇒ | copyreg |
Queue | ⇒ | queue |
SocketServer | ⇒ | socketserver |
markupbase | ⇒ | _markupbase |
repr | ⇒ | reprlib |
test.test_support | ⇒ | test.support |
- Pythonの2.xのモジュールに共通のパターンは、例えばpickleモジュールとcPickleモジュールのように、pure Pythonで実装されたモジュールとともに、オプションとして高速バージョンのCで実装された拡張がある、ということです。このパターンは、高速バージョンを導入しpure Python バージョンに頼る、これらのモジュールを使用するユーザにとって負担になります。Python 3.0では、高速バージョンはpure Python バージョンの実装の詳細とみなされます。高速バージョンを導入し、そしてpure Pythonのバージョンに頼りたい時は、ユーザはいつも標準バージョンを導入すべきです。pickleモジュールとcPickleモジュールのペアは、この処理を受けました。profileモジュールが、3.1のリストに上がっています。StringIOモジュールはioモジュールのクラスになっています。
- 幾つかの関連するモジュール群はパッケージにまとめられています。そして通常サブモジュール名は単純化されています。
結果として新しいパッケージは:
- dbm (anydbm, dbhash, dbm, dumbdbm, gdbm, whichdb).
- html (HTMLParser, htmlentitydefs).
- http (httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib).
- tkinter (turtleモジュールを除く全てのTkinter関連のモジュール) turtleモジュールの対象の聴衆は、本当はtkinterを気にしません。また、Python2.6現在、turtleモジュールの機能性が大いに強化されていることに注意してください。
- urllib (urllib, urllib2, urlparse, robotparse).
- xmlrpc (xmlrpclib, DocXMLRPCServer, SimpleXMLRPCServer).
PEP 3108でカバーされない、標準ライブラリモジュールのいくつかの別の変更:
- setsモジュールを抹消します。組み込みのset関数を使用してください。
- sysモジュールの整理: sys.exitfunc関数、sys.exc_clear関数、sys.exc_type関数、sys.exc_value関数、sys.exc_traceback関数の削除(sys.last_type等は残っていることに注意してください)
- array.array型の整理: readメソッドとwriteメソッドはなくなりました。fromfileメソッドとtofileメソッドを代わりに使用して下さい。また、arrayの'c'タイプコードはなくなりました。bytesオブジェクトのための'b'を、ユニコード文字のための'u'のいずれかを用いてください。
- operatorモジュールの整理: sequenceIncludes関数とisCallable関数の削除
- threadモジュールの整理: acquire_lock関数とrelease_lock関数がなくなりました。acquire関数とrelease関数を代わりに使用してください。
- randomモジュールの整理: jumpahead関数とそのAPIが削除されました。
- newモジュールがなくなりました。
- tempfileモジュールのために、os.tmpnam関数、os.tempnam関数、そしてos.tmpfile関数が削除されました。
- tokenizeモジュールがbytesに対して働くように変更されました。メインのエントリーポイントは、generate_tokensに代わり、今やtokenize.tokenize関数になりました。
- string.lettersとその仲間(string.lowercaseとstring.uppercase)はなくなりました。代わりにstring.ascii_letters等を使用してください。(削除の理由は、string.lettersやその仲間がローカル依存の動作を持っていたからです。そしてそれは、そのように魅力的に名付けられたグローバル「定数」のための悪いアイデアです)。
- __builtin__モジュールがbuiltinsに改称されました(アンダースコアが無くなり、's'が追加されました)殆どのグローバルな名前空間で見出される__builtins__の変数は、変更されていません。『組み込み』を修正するには、__builtins__ではなくbuiltinsを使用する必要があります!
PEP 3101: 文字列書式設定の新しいアプローチ†
- 『%』による文字列書式の操作に代わって、新しい組み込み文字列書式の操作のシステムが置き換えられます。(『%』演算子はまだサポートされてはいますが、Python 3.1 において非推奨となりそれからしばらくあとで言語仕様から削除されます)詳細については PEP 3101を読んでください。
例外処理の変更†
例外の発生や捕捉についてのAPIは整理されました。そして新しく強力な特徴が追加されました:
- [PEP 0352] すべての例外は BaseException から直接間接を問わず派生したものでなければなりません。BaseExceptionは、例外オブジェクトの階層のルートです。これは勧告として新しくありませんが、「BaseExceptionから継承することが必須である」という『必要条件』としては新規です。(Python 2.6ではまだ旧スタイルのクラスが発生できるようになっています。そして、捕捉については特に制限されていません)その結果、文字列による例外は最終的に、真に、そして完全に息の根を止められます。
- ほぼすべての例外は、実質的にはExceptionから派生します。 BaseExceptionが基底クラスとして使われなければならない『例外』は、SystemExitやKeyboadInterruptなどのようにトップレベルを操作しなければならないものに限られます。この後者のカテゴリーを除き、すべての例外を処理するための『例外』のイディオムとしては、Exceptionを使用することです。
- StandardErrorは削除されました(2.6に於いて既に)
- Exceptionsは、もはやシーケンスとして動作していません。そのかわりにargs属性を使用してください。
- [PEP 3109] 例外を発生させる。『raise Exception(args)』を『raise Exception, args』の代わりに使わなければならなくなりました。さらに、もう明示的にトレースバックを指定することはできません。代わりに、もしこれを行うには、直接__traceback__属性に割り当てることができます(下記参照) 。
- [PEP 3110] 例外の捕捉。『except SomeException as variable』を『except SomeException , variable』の代わりに使用しなければならなくなりました。また、variableはexcept節が終わった時、確実に消去されます。
- [PEP 3134] 例外の連鎖。暗黙の連鎖と明示的な連鎖の2例があります。暗黙の連鎖は、例外を処理するexcept節やfinally節の中で例外が発生するときに起きます。これは通常、処理節の中のバグによって発生します。我々はコレを『二次例外』と呼んでいます。この場合、(その時点で処理の真っ最中である)元の例外が二次例外の__context__属性として保存されています。明示的な連鎖この構文で引き起こされます:
raise SecondaryException() from primary_exception
(primary_exceptionはexceptionオブジェクトから生成されたどんな例外でも、多分、それは以前に捕捉されたものでしょう)この場合、主な例外は、二次例外の__cause__属性に格納されています。未処理の例外が__cause__属性と__context__属性の連鎖を渡り歩き、(渡り歩いている連鎖のコンポーネント毎に)分離したトレースバックを出力したときに、最初に最上位の例外を伴ってトレースバックが出力されます(Javaユーザーなら、この現象を理解できるかもしれません)
- [PEP 3134] 例外オブジェクトは__traceback__属性として保存されるようになりました。これは例外オブジェクトに(その)例外に関する情報のすべてが含まれるようになったということです。それにより、sys_exc_info() を使う理由は少なくなりました(とはいえ削除されてはいません)。
- Windowsがで拡張モジュールのロードに失敗したときのメッセージが改善されました。たとえば、 エラーコード193は『%1 は有効なWin32アプリケーションではありません』になりました。(訳注:多分%1とは、バッチファイルで言うプログラム実行時の第一引数のことと思われる)文字列は、英語以外のロケールに対応するようになりました。
雑多なその他の変更†
演算子や特殊メソッド†
- 『!=』は、『==』がNotImplementedを返さない限り、『==』の反対を返すようになりました。
- 『unbound methods(束縛されていないのメソッド)』というコンセプトは言語から削除されました。クラス属性としてメソッドを参照するときは、ただの関数オブジェクトとなりました。
(訳注:
>>> class X:
... def ooo(self, other):
... print(self,other)
...
>>> X.ooo(1,2)
1 2
>>>
……というようなことが出来るようになった、という意味。以前はX.oooはunbound methodsとして、第一引数はXのインスタンス以外は受け付けなかった。この変更の効用としては、クラスを、単なる関数をまとめる入れ物として使いやすくした、と考えられる)
- __getslice__メソッドと__setslice__メソッド、そして__delslice__は抹消されました。。『a[i:j]』構文はa.__getitem__(slice(i, j))に変換されるようになりました(代入や削除の操作をするなら__setitem__メソッドか__delitem__に置き換えられます)
- [PEP 3114] next標準メソッドは、__next__メソッドに改称されました。
(訳注:そのかわりにイテレータオブジェクトの順送りには、next標準関数が使える)
- 特殊メソッド__oct__と__hex__が削除されました。oct関数とhex関数は、整数引数を変換するために__index__メソッドを使用するようになりました。
- __members__と__methods__のサポートが打ち切られました。
- func_Xと名づけられていた関数の属性は、__X__というフォームに改称されました。古いfunc_X形式の名前は関数の属性の名前空間は、ユーザが定義する属性(名)として解放されました。即ちfunc_closure、func_code、func_defaults、func_dict、func_doc、func_globals、func_nameはそれぞれ__closure__、__code__、__defaults__、__dict__、__doc__、__globals__、__name__に改称されました。
- __nonzero__メソッドは、__bool__メソッドになりました。
組み込み(関数,オブジェクト,型など)†
- [PEP 3135] 新super関数。super関数を引数無しで呼び出すと、正しいクラスとインスタンスが自動的に選択されるようになりました(これは、クラス文の中で定義された普通のインスタンスメソッドを想定しています)引数つきの super関数の動作には変更ありません。
- [PEP 3111] raw_input関数がinput関数に改称されました。つまり、新しいinput関数はsys.stdinから1行を読み取り、末尾の改行を除去してそれを返します。入力が完了せずに打ち切られると、EOFErrorが発生します。古いinput関数の動作(の結果)を取得するには『eval(input())』を使用してください。
- 新しい組み込み関数のnextは、オブジェクトの__next__メソッドを呼び出すために追加されました。
- intern関数はsys.intern関数へ移動しました。
- apply関数は削除されました。『apply(f, args)』の代わりに、『f(*args)』を使用してください。
- callable関数は削除されました。『callable(f)』の代わりに、『hasattr(f, '__call__')』が使えます。operator.isCallable関数もなくなりました。
- coerce関数は削除されました。この関数は、もはや旧スタイルのクラスが無くなった今、なんの用途も提供しません。
- execfile関数は削除されました。『execfile(fn)』の代わりに『exec(open(fn).read())』を使用します。
- file関数が削除されました。open関数を使用してください。
- reduce関数が削除されました。もし本当に必要なら、functools.reduce関数を使ってくださいとはいえ、99パーセントの場合、明示的な『for ループ』のほうが読みやすくなります。
- reload関数は削除されました。imp.reload関数を使用してください。
- dict.has_keyメソッドは削除されました。in 演算子を使用してください。
ビルドとC言語へのAPIの変更†
時間の制約があるため、これでは、 C言語へのAPIの変更の、非常に不完全なリストです。
- Mac OS 9やBeOSやRISCOSやIrix、そしてTru64を含め、そしてそれに限らず、いくつかのプラットフォームのサポートの提供が打ち切られました。
- [PEP 3118] 新しいBuffer API.
- [PEP 3121] 拡張モジュールの初期化と終了作法。
- [PEP 3123] PyObject_HEADが標準Cに準拠されました。
- 実行を制御するためのC APIは、もうサポートされていません。
- CのAPIのPyNumber_Coerce、PyNumber_CoerceEx、PyMember_Get、とPyMember_Setは、削除されました。
- 新しいCのAPIのPyImport_ImportModuleNoBlockは、PyImport_ImportModuleのように働きます。しかし、import lockをブロックしません(代わりにエラーを返します)
- Cレベルのスロットとメソッドのブール変換の改称:nb_nonzeroはnb_boolになりました。
- METH_OLDARGSとWITH_CYCLE_GCがCのAPIから削除されました。
パフォーマンス†
3.0の一般化の正味の結果は、pystoneベンチマークでPython3.0がPython2.5より約10%遅く走るということです。おそらく、最も大きな原因は小さな整数のための特殊なケーシングの除去にあるのでしょう。実装に改善の余地があるけれども、3.0がリリースされた後に、それは起こるでしょう!
Python 3.0への移植†
既存のPython 2.5または2.6のソースコードをPython 3.0に移植するための最適な戦略は以下の通りです:
0. (前提条件)優れたテスト適用から開始します。
1. Python 2.6へ移植。このステップは、Python 2.x からPython 2.(x+1)への平均的な移植作業以上の手間はかからないでしょう。すべてのテストに合格していることを確認。
2. (まだ2.6を使用して)-3コマンドラインスイッチを(ひねって)ONにします。このスイッチを指定することによって、3.0で削除されたり変更されるような機能についての警告を行います。再度テストスイートを走らせます。警告が一切なくなり全てのテストを通過するまで(テストにパスするまで)コードの修正を行います。
3. 2→3コード変換ツールをソースコードツリーに対して走らせます。(2to3を参照のこと - このツールで自動的にPython2から3のコード変換以上のことをしてくれます) 変換結果をPython 3.0下で走らせます。再びすべてのテストを通過するまで手作業で残る懸案事項を修正して、問題を解決してください。
Python2.6と3.0両方の下で不変になるソースコードを書き込もうとすることは、お勧めできません;あなたは、まさしくその曲げられたコーディングスタイル、たとえば、print文やメタクラスやあるいはもっと多くの多くのものを避けることを強要されるでしょうから。あなたが、Python 2.6とPython 3.0の両方をサポートする必要があるライブラリをメンテナンスしているならば、最もよいアプローチは、3.0バージョンのソースコードを編集するよりも、修正ステップ3に従って2.6バージョンのソースコードを編集し、再び2to3トランスレータを実行することでしょう。
C拡張のPython3.0への移植のためには、どうぞ『Porting Extension Modules to 3.0』をご覧下さい。
訳出 機械伯爵(in TSNET)
翻訳についてのおことわり†
この文を訳出するに当たって、以下のルールを適用しました
- 固有のモジュール名やオブジェクト名、あるいは日本語訳を行うのが不適当と思われる箇所は、原文のままとしました
- xxx()の形式となっているものは、便宜上全て「〜関数」と訳しました。Pythonに詳しい方々は、これらのうち多くの実体が、が本来は関数オブジェクトではなく、クラスのコンストラクタであったり、あるいはオブジェクトであったりすることをご存知だと思いますが「呼び出して(プログラミング言語一般的な意味の)関数的に使用する」という意味で、あえてこの方式をとりました。ただし、明らかにオブジェクトに属するメソッドである(メソッド的な使用法……ob.meth()のような)ものについては、「〜メソッド」と訳しました
- 文中の書式/記法などについては、原文中の表現に関係なく『』(白かぎかっこ)で囲う形に統一しました
- 文中の表現では内容が不鮮明と思われる箇所は、訳注として適宜補足しました
- 本文を訳出するに当たって、TSNETのBruce.さん、Fe2+さんに校正していただきました(元の訳文は『機械』訳だけに人の読めるモノではありませんでした。ありがとうございます)
関連ページ†
リンク†
コメント、修正記録など†
コメント†