What's New In Python 3.1¶
- 著者
Raymond Hettinger
この記事では 3.0 と比較した Python 3.1 の新機能を解説します。Python 3.1 は2009年6月27日にリリースされました。
PEP 372: 順序付き辞書¶
通常の Python 辞書は、 key/value ペアを不定の順序でイテレートします。何年にもわたり、いろいろな人が key の挿入順を保存する辞書の別実装を書いてきました。その経験に基づき、新しい OrderedDict
クラスが導入されました。
OrderedDict API は通常の辞書と同じインターフェースを提供していますが、 key/value をイテレートするときに key が最初に挿入された順番になることが保証されています。新しいエントリが既存のエントリを上書きした場合は、元の挿入順序が保持されます。エントリを削除して再挿入すると、順序は一番最後に移動します。
標準ライブラリのいくつかのモジュールで、順序付き辞書の利用がサポートされています。configparser
モジュールはデフォルトで順序付き辞書を使います。設定ファイルを読み込み、編集した後、元の順序で書きなおすことができます。collections.namedtuple()
の _asdict() メソッドは、タプルの順序と同じ順序の順序付き辞書を返すようになりました。json
モジュールのデコーダーが OrderedDict をビルドするのをサポートするために、 JSONDecoder
クラスのコンストラクタに object_pairs_hook 引数が追加されました。 PyYAML などの外部のライブラリでもサポートされています。
参考
- PEP 372 - 順序付き辞書
PEP written by Armin Ronacher and Raymond Hettinger. Implementation written by Raymond Hettinger.
PEP 378: 1000区切りのための書式指定子¶
組み込みの format()
関数と str.format()
メソッドが使うミニ言語に、単純でロケールに依存しない 1000 区切りカンマの書式化が追加されました。これによって簡単にプログラムの出力を、その玄人ちっくな見た目を改善してひとさまにとって読みやすいものに出来ます:
>>> format(1234567, ',d')
'1,234,567'
>>> format(1234567.89, ',.2f')
'1,234,567.89'
>>> format(12345.6 + 8901234.12j, ',f')
'12,345.600000+8,901,234.120000j'
>>> format(Decimal('1234567.89'), ',f')
'1,234,567.89'
これをサポートする型は int
, float
, complex
, decimal.Decimal
です。
ドットやら空白やらアポストロフィやらあるいはアンダースコアなどの他のセパレータをどうやって指定するかの議論は水面下にありますが、ロケールに従う必要があるアプリケーションは、1000区切りセパレータについていくつかのサポートを既に持っている既存の n 指定子を使うべきです。
参考
- PEP 378 - 1000区切りのための書式指定子
PEP written by Raymond Hettinger and implemented by Eric Smith and Mark Dickinson.
その他の言語変更¶
Python 言語コアに小さな変更がいくつか行われました:
__main__.py
を含むディレクトと zip アーカイブを、その名前をインタプリタに渡すことで直接実行出来るようになりました。そのディレクトリと zip ファイルは自動的に sys.path エントリの先頭に挿入されます。(Suggestion and initial patch by Andy Chu; revised patch by Phillip J. Eby and Nick Coghlan; bpo-1739468.)int()
型にbit_length
メソッドが追加されました。 このメソッドはその値を二進数で表現するのに必要なビット数を返します:>>> n = 37 >>> bin(37) '0b100101' >>> n.bit_length() 6 >>> n = 2**123-1 >>> n.bit_length() 123 >>> (n+1).bit_length() 124
(Contributed by Fredrik Johansson, Victor Stinner, Raymond Hettinger, and Mark Dickinson; bpo-3439.)
format()
文字列のフィールドに自動的に番号が振られるようになりました:>>> 'Sir {} of {}'.format('Gallahad', 'Camelot') 'Sir Gallahad of Camelot'
以前は、文字列は
'Sir {0} of {1}'
のようにフィールドに番号を振らなければなりませんでした。(Contributed by Eric Smith; bpo-5237.)
string.maketrans()
関数は撤廃され、それぞれの静的メソッドbytes.maketrans()
とbytearray.maketrans()
に置き換えられました。この変更は、string
によってサポートされるのがどちらの型なのかにまつわる混乱を解決します。今やstr
,bytes
,bytearray
は、その適切な型の中間変換テーブルを持つそれぞれの maketrans 、 translate メソッドを持っています。(Contributed by Georg Brandl; bpo-5675.)
with
文のシンタックスは一つの文で複数のコンテキストマネージャを使えるようになりました:>>> with open('mylog.txt') as infile, open('a.out', 'w') as outfile: ... for line in infile: ... if '<critical>' in line: ... outfile.write(line)
新しい構文によって
contextlib.nested()
関数はもう必要ではなくなり、非推奨になりました。(Georg Brandl と Mattias Brändström の貢献; appspot issue 53094.)
round(x, n)
は x が整数の場合、整数を返すようになりました。以前は浮動小数点を返していました:>>> round(1123, -2) 1100
(Contributed by Mark Dickinson; bpo-4707.)
Python は浮動小数点数について、その値を変更しない最も短い表現を見つけるのに David Gay のアルゴリズムを使うようになりました。これは二進浮動小数点数にまつわるいくつかの困惑を軽減する助けとなるはずです。
有意な違いは
1.1
のような値ですぐに見て取れます。これは二進浮動小数点数で正確に表現出来ない数です。完全に同じとなるものはありませんから、例えば式float('1.1')
は表現可能な最近接である十六進での0x1.199999999999ap+0
、十進での1.100000000000000088817841970012523233890533447265625
として評価されます。その最近接値は昔も今も、後続の浮動小数点数計算で使われます。何が新しくなったかと言えば、それはその数がどのように表示されるか、です。以前は Python は単純なアプローチを使っていました。値
repr(1.1)
はformat(1.1, '.17g')
として計算され、'1.1000000000000001'
として評価されていました。17 桁を使うことが好都合だったのは、IEEE-754 のもとではeval(repr(1.1))
がその元の値に正確に戻ることに依存出来たことでした。ですが不都合として、多くの人々がその出力を (二進浮動小数点数表現に本来備わっている制限を Python そのものの問題であると誤解して) 混乱していると理解していました。新しいアルゴリズムでは
repr(1.1)
はより賢明で'1.1'
を返します。実際的には、これは全ての等価な文字列表現 (前提となる同じ浮動小数点数に戻るもの) を探し、そして一番短い表現を返します。新アルゴリズムは、可能な限りよりわかりやすい表現を生み出す傾向がありますが、元の値を変更しません。ですから
1.1 + 2.2 != 3.3
は表示がどうであれ、今でも問題です。新アルゴリズムは根底にある浮動小数点数実装の、ある機能に依存しています。その必要としている機能がないならば、古いアルゴリズムが引き続き使われます。なお、テキストの pickle プロトコルは、このアルゴリズム変更によりクロスプラットフォーム互換が保たれません。
(Contributed by Eric Smith and Mark Dickinson; bpo-1580)
新たなモジュール、改良されたモジュール、非推奨のモジュール¶
シーケンスまたはイテラブル内にある一意な要素を数え上げるのに便利な
collections.Counter
クラスが追加されました:>>> Counter(['red', 'blue', 'red', 'green', 'blue', 'blue']) Counter({'blue': 3, 'red': 2, 'green': 1})
(Contributed by Raymond Hettinger; bpo-1696199.)
Tk のテーマ付きウィジェットへのアクセスを提供する、新しい
tkinter.ttk
モジュールが追加されました。tkinter.ttk
の基本的なアイディアは、拡張可能性のためにウィジェットの動作を実装するコードと見た目を記述するコードを分離することです。(Contributed by Guilherme Polo; bpo-2983.)
gzip.GzipFile
とbz2.BZ2File
クラスはコンテキストマネジメントプロトコルをサポートするようになりました:>>> # Automatically close file after writing >>> with gzip.GzipFile(filename, "wb") as f: ... f.write(b"xxx")
(Contributed by Antoine Pitrou.)
decimal
モジュールが二進float
から decimal オブジェクトを生成するメソッドをサポートしました。 変換は正確ですが時に意外なことがあります:>>> Decimal.from_float(1.1) Decimal('1.100000000000000088817841970012523233890533447265625')
長い十進の結果が、 1.1 を記憶するための現実の二進での端数を表しています。 1.1 は二進数で正確に表現出来ないので、端数は十進表現でとても多くの桁数になっています。
(Contributed by Raymond Hettinger and Mark Dickinson.)
itertools
に 2 つの関数が追加されました。itertools.combinations_with_replacement()
関数は、置換 (順列, permutation) や直積 (Cartesian product) を含む組合せ論の 4 つの生成関数のうちの 1 つです。itertools.compress()
関数は APL の同名機能の模倣品です。また、既存のitertools.count()
関数は新たにオプショナルな step 引数を取るようになり、そして数え方にfractions.Fraction
やdecimal.Decimal
を含む任意の数値型を使えるようになりました。>>> [p+q for p,q in combinations_with_replacement('LOVE', 2)] ['LL', 'LO', 'LV', 'LE', 'OO', 'OV', 'OE', 'VV', 'VE', 'EE'] >>> list(compress(data=range(10), selectors=[0,0,1,1,0,1,0,1,0,0])) [2, 3, 5, 7] >>> c = count(start=Fraction(1,2), step=Fraction(1,6)) >>> [next(c), next(c), next(c), next(c)] [Fraction(1, 2), Fraction(2, 3), Fraction(5, 6), Fraction(1, 1)]
(Contributed by Raymond Hettinger.)
collections.namedtuple()
が新たにキーワード引数 rename をサポートし、これにより不正なフィールド名を自動で _0, _1, ... といった位置による名前に変換することが出来ます。これはフィールド名が何か外部ソースに基いて作られる場合に有用です。例えば CSV のヘッダ、SQL のフィールドリスト、あるいはユーザ入力などです:>>> query = input() SELECT region, dept, count(*) FROM main GROUPBY region, dept >>> cursor.execute(query) >>> query_fields = [desc[0] for desc in cursor.description] >>> UserQuery = namedtuple('UserQuery', query_fields, rename=True) >>> pprint.pprint([UserQuery(*row) for row in cursor]) [UserQuery(region='South', dept='Shipping', _2=185), UserQuery(region='North', dept='Accounting', _2=37), UserQuery(region='West', dept='Sales', _2=419)]
(Contributed by Raymond Hettinger; bpo-1818.)
re.sub()
、re.subn()
およびre.split()
関数は flags 引数を受け取るようになりました。(Contributed by Gregory Smith.)
logging を自身では使わずとも使用ライブラリがそうしているようなアプリケーションのために、
logging
モジュールが単純なlogging.NullHandler
を実装しました。null ハンドラをセットアップすることは、 "No handlers could be found for logger foo" のような警告を抑制します。>>> h = logging.NullHandler() >>> logging.getLogger("foo").addHandler(h)
(Contributed by Vinay Sajip; bpo-4384).
コマンドラインスイッチ
-m
をサポートしているrunpy
がパッケージの実行をサポートするようになりました。パッケージ名が与えられると__main__
サブモジュールを探し出して実行します。(Contributed by Andi Vajda; bpo-4195.)
pdb
モジュールがzipimport
(あるいはなにかほかの PEP 302 準拠ローダ) でロードされたモジュールのソースコードにアクセスでき、表示できるようになりました。(Contributed by Alexander Belopolsky; bpo-4201.)
functools.partial
オブジェクトが pickle 化出来るようになりました。
(Suggested by Antoine Pitrou and Jesse Noller. Implemented by Jack Diederich; bpo-5228.)
シンボルのための
pydoc
ヘルプトピックが追加されました。これで対話環境でhelp('@')
などが期待通りの働きをします (---訳注: 実装としては pydoc_data パッケージのこと。pydoc_data/topics.py
に docstring からは生成出来ない、シンボルについてのドキュメントが収められています ---)。(Contributed by David Laban; bpo-4739.)
unittest
に特定のテストメソッドやテストクラス全体をスキップする仕組みのサポートが追加されました。さらに、この機能はテスト結果を「意図的な失敗」とすることができ、テストが失敗してもTestResult
の失敗数にはカウントされなくなります:class TestGizmo(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") def test_gizmo_on_windows(self): ... @unittest.expectedFailure def test_gimzo_without_required_library(self): ...
また例外についてのテストが、
with
文で使えるコンテキストマネージャとして増強されました:def test_division_by_zero(self): with self.assertRaises(ZeroDivisionError): x / 0
加えて、いくつもの新たなアサーションメソッドが追加されました。
assertSetEqual()
,assertDictEqual()
,assertDictContainsSubset()
,assertListEqual()
,assertTupleEqual()
,assertSequenceEqual()
,assertRaisesRegexp()
,assertIsNone()
, andassertIsNotNone()
などです。(Contributed by Benjamin Peterson and Antoine Pitrou.)
io
モジュールにseek()
メソッドのための3つの新しい定数が追加されました:SEEK_SET
,SEEK_CUR
, andSEEK_END
.sys.version_info
タプルが名前付きタプルになりました。>>> sys.version_info sys.version_info(major=3, minor=1, micro=0, releaselevel='alpha', serial=2)
(Contributed by Ross Light; bpo-4285.)
pickle
を、プロトコル 2 以下を使う際に Python 2.x との相互運用に順応するようにしました。標準ライブラリの再編成はたくさんのオブジェクトへの公式な参照を変えました。例えば Python 2 の__builtin__.set
は Python 3 ではbuiltins.set
です。この変化は異なる Python バージョン間でのデータ共有の取り組みを複雑にしました。ですが今回のこの修正により、プロトコル 2 以下を選んだ場合は pickler は自動的にロード時もダンプ時も古い Python 2 命名を使うようになります。この再マッピングはデフォルトで有効になりますが、 fix_imports オプションで無効に出来ます:>>> s = {1, 2, 3} >>> pickle.dumps(s, protocol=0) b'c__builtin__\nset\np0\n((lp1\nL1L\naL2L\naL3L\natp2\nRp3\n.' >>> pickle.dumps(s, protocol=0, fix_imports=False) b'cbuiltins\nset\np0\n((lp1\nL1L\naL2L\naL3L\natp2\nRp3\n.'
不幸にも、そして避けられないこの変更による副作用は、Python 3.1 によって生成されたプロトコル 2 pickle が Python 3.0 で読めなくなるであろうことです。Python 2.x との互換性を維持するつもりがないのであれば、Python 3.x 実装間でのデータ移行では最新 pickle プロトコルバージョン 3 を使うべきです。
(Contributed by Alexandre Vassalotti and Antoine Pitrou, bpo-6137.)
新規モジュール
importlib
が追加されました。import
文とその相棒の__import__()
関数の、完全で移植性が高いピュア Python 参照実装を提供しています。これはインポートで行う動作の文書化と定義における、確かな前進です。(Contributed by Brett Cannon.)
最適化¶
大きな性能向上がありました:
The new I/O library (as defined in PEP 3116) was mostly written in Python and quickly proved to be a problematic bottleneck in Python 3.0. In Python 3.1, the I/O library has been entirely rewritten in C and is 2 to 20 times faster depending on the task at hand. The pure Python version is still available for experimentation purposes through the
_pyio
module.(Contributed by Amaury Forgeot d'Arc and Antoine Pitrou.)
Added a heuristic so that tuples and dicts containing only untrackable objects are not tracked by the garbage collector. This can reduce the size of collections and therefore the garbage collection overhead on long-running programs, depending on their particular use of datatypes.
(Contributed by Antoine Pitrou, bpo-4688.)
Enabling a configure option named
--with-computed-gotos
on compilers that support it (notably: gcc, SunPro, icc), the bytecode evaluation loop is compiled with a new dispatch mechanism which gives speedups of up to 20%, depending on the system, the compiler, and the benchmark.(Contributed by Antoine Pitrou along with a number of other participants, bpo-4753).
UTF-8, UTF-16 ならびに LATIN-1 のデコーディングが2から4倍速くなりました。
(Antoine Pitrou と Amaury Forgeot d'Arc の貢献, bpo-4868.)
The
json
module now has a C extension to substantially improve its performance. In addition, the API was modified so that json works only withstr
, not withbytes
. That change makes the module closely match the JSON specification which is defined in terms of Unicode.(Contributed by Bob Ippolito and converted to Py3.1 by Antoine Pitrou and Benjamin Peterson; bpo-4136.)
Unpickling now interns the attribute names of pickled objects. This saves memory and allows pickles to be smaller.
(Contributed by Jake McGuire and Antoine Pitrou; bpo-5084.)
IDLE¶
IDLE のフォーマットメニューに、ソースコードから末尾の空白を取り除くことが出来るオプションが追加されました。
(Contributed by Roger D. Serwy; bpo-5150.)
ビルドならびに C API の変更¶
Python のビルド過程と C API の変更は以下の通りです:
整数の内部格納方式が
2**15
ベースと2**30
ベースのいずれかになりました。 これはビルド時に決定されます。 以前は常に2**15
ベースで格納されていました。2**30
ベースにすると 64 bit マシンでは性能が有意に向上しますが、 32 bit マシンでのベンチマーク結果には向上も低下もあります。 そのため、デフォルトでは 64 bit マシンで2**30
ベースを、 32 bit マシンで2**15
ベースを使用します。 Unix では新たな configure オプション--enable-big-digits
が追加されました。 これにより上記のデフォルトを上書き出来ます。この変更は性能向上以外ではエンドユーザには分からないはずですが、例外が1つあります。 テストおよびデバッグ目的で内部形式の情報を提供する
sys.int_info
が追加されましたが、これにより数字あたりのビット数と各数字の格納に使われる C の型のバイトサイズが分かります:>>> import sys >>> sys.int_info sys.int_info(bits_per_digit=30, sizeof_digit=4)
(Contributed by Mark Dickinson; bpo-4258.)
PyLong_AsUnsignedLongLong()
関数は負の pylong に対しTypeError
ではなくOverflowError
を送出するようになりました。(Contributed by Mark Dickinson and Lisandro Dalcrin; bpo-5175.)
PyNumber_Int()
が非推奨になりました。代わりにPyNumber_Long()
を使用してください。(Contributed by Mark Dickinson; bpo-4910.)
非推奨の関数
PyOS_ascii_strtod()
およびPyOS_ascii_atof()
を置き換えるために新しくPyOS_string_to_double()
関数が追加されました。(Contributed by Mark Dickinson; bpo-5914.)
PyCObject
API を置き換えるものとして、PyCapsule
が追加されました。主な違いとしては、新しい型は、型安全に情報を渡すための良く定義されたインターフェイスを持ち、また、デストラクタの呼び出しのシグネチャの複雑さが小さくなっています。古い型は問題のある API で、今では非推奨です。(Contributed by Larry Hastings; bpo-5630.)
Python 3.1 への移植¶
このセクションでは前述の変更とバグフィックスにより必要となるかもしれないコードの変更を列挙します:
新しい浮動小数点の文字列表現は既存の doctest に違反する惧れがあります。例えば、
def e(): '''Compute the base of natural logarithms. >>> e() 2.7182818284590451 ''' return sum(1/math.factorial(x) for x in reversed(range(30))) doctest.testmod() ********************************************************************** Failed example: e() Expected: 2.7182818284590451 Got: 2.718281828459045 **********************************************************************
pickle モジュールがプロトコルバージョン 2 以下で自動的に名前の再対応付けを行うので、Python 3.1 で pickle 化すると Python 3.0 で読めなくなります。一つの解決策はプロトコル 3 を使うことです。もう一つは fix_imports オプションを
False
にセットすることです。上述の議論を参照してください。