よりPythonicなPythonを目指して[後編]
言語としての一貫性を重視した
Python 3の進化
柴田 淳
ウエブコア株式会社
2009/02/06
Python 3.0では、Python 2で書かれたスクリプトが動かなくなるような実装が行われた。なぜ、後方互換性を崩してまで大きな仕様変更を行ったのか。それは、PythonがよりPythonらしくあるためだ。
- - PR -
前編「Python 3が後方互換性を捨てても求めたもの」では、後方互換性を犠牲にしてでも、よりPythonらしくあるために仕様を変更したことに触れながら、いくつかの機能変更を見てきました。
それは、「誰もが正しいと考える、たった1つの方法をできる限り採用する(There should be one―and preferably only one―obvious way to do it)」というPythonの設計思想を、より高次元で実現するために必要だったからです。
引き続き、後編ではPython 3.0で変更された仕様や新たに追加された機能を追いながら、Pythonという言語が目指す進化の方向性を探ってみましょう。
int型の統合、数値の扱いの変更
Python 2では、文字列型だけでなく、整数型にも2つの種類がありました。C言語のlong型に依存したint型です。もう1つは、メモリの許す限り大きな数値を扱えるlong型です。
もともと精度の低いint型がPythonに作られ、より大きな数値を扱いたいという要求からlong型が追加されました。int型とlong型をリテラルで書き分けられるように、数字の末尾に「L」を付けるというlong型のためのリテラルが用意されました。
整数のための型が2種類あることも、古くからPythonの言語実装の一貫性を崩す仕様として議論されてきました。Pythonでは、仕様変更や機能追加に先だってPEPと呼ばれる技術文書が公開されます。PEP 237にint型とlong型を統合し、long型のみを整数型として採用するという提案がなされています。
一見簡単そうに見える整数型の統合ですが、細かく見るといろいろな問題を引き起こす可能性をはらんでいます。PEPには、後方互換性に関する考察が書かれています。以下はその一部です。
- 統合によってlong型のリテラルが廃止され、プログラムの修正が要求される
- ビットシフト演算で、int型はビット落ちを起こすが、long型はビット落ちを起こさない
- int型の0xffffffffは-1相当になるが、long型として解釈すると2の32乗-1となる
前編で紹介したように、Python 3.0では後方互換性を崩す仕様変更が許されました。そこで、2種類の整数型が統合され、long型相当の数値型に統一されました。PEP 237が提出されたのは2001年ですから、7年以上も統合が見送られていたことになります。
また、Python 2までは、int型同士の割り算は必ずint型を返していました。結果が小数点を含む数値となった場合は、内輪で一番近い整数を結果としていました。「1/2」の結果は「0」になります。
Python 3.0では、int型同士の割り算は必ずfloat型の数値を返します。なお、従来通りint型を得たい場合には「//」という演算子を使います。
数値型関連の機能追加では、ほかに2進数を扱う「0b1010」というリテラル表記が追加されています。Python 2までは8進数を扱うリテラルが「0666」だったのが、英語の8進数を意味する「Octal notation」からとった「O(オー)」を使った「0o666」というリテラルに変更されています。
16進数が「0xABCD」のような表記ですので、数値のリテラル表記も、拡張をしながら一貫性を持ったものに変更されていることが分かります。
イテレータとview
Python 3.0では、これまでリストを返していたメソッドや組み込み関数がイテレータやview(ビュー)と呼ばれる軽量のイテレータ風オブジェクトを返すようになりました。
関連した仕様変更でもっとも目立つのは、組み込み関数xrange()とrange()の統合かもしれません。xrange()もrange()も、for文などに添えて使い、順番に増減するシンプルな数値のリストを生成するために利用されます。
Python 2までのrange()はリストを生成します。このため、何十万回も繰り返し処理を行うような場合はメモリ効率が悪くなってしまいます。range()を呼び出すと、繰り返しの回数に必要な何十万もの要素を持ったリストを事前にメモリ上に用意するからです。
そのため、このような場合はxrange()を使いました。xrange()はイテレータ風のオブジェクトを生成します。数を順番に生成するだけなので、すべての要素をメモリ上に置かないため、メモリの使用効率上利点があるのです。
Python 3.0では、range()関数がイテレータ風のオブジェクトを返すようになり、xrange()が不要になったため廃止になりました。状況によって使い分ける必要があった2つの関数が1つに統合されて、より一貫性が増したわけです。
Python 2.2でイテレータが追加されたときから、range()とxrange()統合の議論はあったのですが、Python 3.0でやっと統合されたことになります。
range()だけでなく、map()やfilter()、zip()といったリストを返していた関数も、イテレータを返すようになります。map()関数では、引数として与えたシーケンスに対して、一度に処理をするのではなく、逐次処理をするようになるわけです。
辞書のような組み込み型のメソッドにもリストを返すものがありました。辞書オブジェクトのキー一覧を返すkeys()、値一覧を返すvalues()、キーと値のペアを一覧で返すitems()といったメソッドがその例です。
これらのメソッドは、リストより軽量で粒度の低いイテレータ風のviewと呼ばれるオブジェクトを返すようになりました。
Python 3で辞書オブジェクトのkeys()を呼び出すと、dict_keysという名前のオブジェクトが返ってきます。これがviewと呼ばれるタイプのオブジェクトです。イテレータと同じ働きをして、イテレーションのたびに次のオブジェクトを返します。自分自身では値を保持せず、呼び出し元の辞書オブジェクトにリファレンスを張るような形でキー一覧を返します。
Python 3.0で、メソッドの返すviewを変数に代入してみましょう。
$ python3.0 |
このように、viewオブジェクトは辞書本体とのリファレンスを保っているだけなので、辞書本体にキーが追加されるとviewの結果も更新されます。
keys()が返すキーの一覧は、辞書オブジェクト自体が内部に持っています。Python 2までは、辞書オブジェクトがすでに持っている情報を、わざわざリストに変換していたわけです。
Pythonのリストは、メモリ領域伸張のコストを下げるため、あらかじめ要素数以上のメモリ空間を占有します。表面で見える以上に粒度の大きなオブジェクトなのです。リストオブジェクトの生成にオーバーヘッドが大きいため、もっと粒度の低いオブジェクトを使うべきという議論がありました。そのため、今回のような仕様変更が行われたのです。
リストを返していたメソッドや組み込み関数が、イテレータやviewを返すようになったため、リストであることを期待したコードは修正が必要になります。例えば、関数の戻り値に直接インデックスを指定するようなコードは、動かなくなってしまいますので注意が必要です。
1/2 |
| Index | |
| 言語としての一貫性を重視したPython 3の進化 | |
| Page1 int型の統合、数値の扱いの変更 イテレータとview |
|
| Page2 より明確な文法となった「例外」 モジュールの統合や改名 Python 3の進化の方向性 |
|
| よりPythonicなPythonを目指して |
- PHPでGAE上に社員検索アプリを作る (2010/3/18)
GAEの制約により使うことができなかったテンプレートエンジン。PHP4GではSmartyが使えるようになった - 構造体の便利な用途、インターフェイス入門 (2010/3/10)
継承機能を排除したインターフェイス機能でダックタイピングが可能となった。サンプルで確かめてみよう - プライベートモードの履歴状態 (2010/3/1)
仕事に集中できるときと、なかなかできないとき、ありますよね。状態遷移図で考えてみよう - Goのswitch文で解くFizzBuzzと構造体のイントロ (2010/2/25)
Goではif文と同等の制御構造をswitch文で表現できる。試してみよう
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
| 「いつかは壊れるサーバ」そんな故障に 迅速で安価に手軽に対応する方法とは? New! |
| 「特権ユーザー」の事件を防げ! 万能権限を持つユーザーの管理方法とは? New! |
| 仮想環境の構築とデータ保護の特効薬?! 実績と信頼性の高いパッケージで安心運用 |
| 仮想環境のバックアップもこれまでどおり 「まるごと取ってまるごと戻す」簡単運用 |
| おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |
| その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |
| 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |
| 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |
お勧め求人情報

**先週の人気講座ランキング**
〜CCNA編〜
| ◆ | TomcatやJBossなどAPサーバ環境に関する 情報を集約! “業務”用APサーバ大百科 New! |
| ◆ | 一気に解説! 最新のクラスタストレージ 「RAIDを超えたストレージ基準」……など New! |
| ◆ | クラウド的ユーザー体験の変化は脅威か? 仮想化技術を使いこなす運用管理術を紹介 New! |

| ◆ | 上司や部下、部署内メンバーとの情報共有 を“ガラッ”と変えるコラボツールとは? New! |
| ◆ | おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| ◆ | 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |

| ◆ | Twitterのアカウントはなぜ突破された? メールによる新手の攻撃手法とその対策 |
| ◆ | もう仮想化のお試しフェイズは終わりだ! Hyper-V 2.0が基幹システムも仮想化 |
| ◆ | 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |

| ◆ | クライアント企業から求められる人材 ⇒IT技術と経営戦略を併せ持つ「戦略家」 |
| ◆ | .NET編集長が実践する「技術情報検索術」 サンプル・コードを簡単に探す“技”は? |
| ◆ | 業務効率と情報セキュリティ対策を両立! 手間なく確実に機密情報を守る方法とは? |

| ◆ | 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| ◆ | 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |

| ◆ | 【CTC事例】約30の基幹システムを統合! 膨大なバッジジョブを制御した方法は? |
| ◆ | 仮想化すればコストは削減できるか? 仮想化に必要な「3つの視点」を解説する |
| ◆ | その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |






