2012-03-18

Python Developer Festa 2012.03 に行きました。

Python Developer Festa 2012.03 で、Python 3.3 チラ見を紹介しました。いくつか補足を。

文字列の扱い

non-BMP Unicode 文字を適切に扱える、の話ですが、何人かの人に指摘されたとおり、Python 3.2 であっても、configure で --with-wide-unicode オプションをつけると、1文字を1文字として扱います。というわけで調べ直しました。

Python 3.2 では、内部で UCS-2 を使う narrow ビルドと、UCS-4をつかう wide ビルドををコンパイル時に選択できるオプションがありました。configure の --with-wide-unicode を明に指定すると、UCS-4です。 この実装の問題は、narrow ビルドでは、サロゲートペアを使う(e.g. 文字列としてのバナナ)が、内部表現としてペア、つまり2文字として扱われていたことです。これが発表で話した内容です。

一方、wide ビルドでは、上記の問題はありません。代わりに、すべての文字に 4 バイト使うので、メモリ効率が悪いという、別の問題がありました。

Python 3.3 は、Python コードから見ると wide ビルド相当の実装のみが提供されます。そして、文字列(文字ではなくて、文字列)の内部表現として、その文字列が 1バイトで表せるか、2バイトか、4バイトか、という情報をもつようになります。これにより、たとえば ASCII 文字のみで構成された文字列では、1バイト/文字使います。一方、Unicode 4.0 で定義されるような絵文字が含まれる場合には、4バイト/文字を使います。

Django プロジェクトによる調査では、以前の方式よりも、Python3.3 方式のほうがメモリ効率がよいそうです。

PEP 393 Flexible String Representation

サブジェネレータ

単純な例を示しました。が、実は、意味があるのは、値を単純に順番に取り出すようなイテレータとして使うときではなく、コルーチンとして使うような場合だと思います。が、まず私があんまりコルーチンにするメリットや、書き方をわかっていないので、いい例が思いつきませんでした(コンストラクタと send() メソッドがあるクラスでいいのに、とか思っていしまいます)。 What's New in Python 3.3 には、この種の用途での例があります。が、ちょっとこれは、LT で説明するにはややこしいなぁ、けど、いい例も思いつかないしなぁと。別の機会にかけたらなと思います。

おわりに

Python 3.3 の仕様はまだ決まっていないので、継続的に見ていって、リリース時にまとめられるといいですね。そのころには、本家のドキュメントにわかりやすい例が載っているのかも知れませんが。