デザインと歴史 FAQ
******************


Python はなぜ文のグループ化にインデントを使うのですか？
=======================================================

Guido van Rossum の信じるところによれば、インデントによるグループ化は
非常にエレガントで、普通の Python プログラムを大いに読みやすくします。
しばらくすればほとんどの人はこの仕様を気に入るようになります。

開始/終了の括弧がないので、構文解析器と人間の読者の間にグループ化の解
釈の違いは起こりえません。時折、C のプログラマはこのようなコード片に出
くわします:

   if (x <= y)
           x++;
           y--;
   z++;

この条件文が真の時のみ実行されるのは "x++" 文だけですが、このインデン
トでは誤解を招きます。経験を積んだ C プログラマでさえ、 "y" が "x > y"
の時にもデクリメントされるのはなぜか分からず長いこと立ち止まることがあ
るでしょう。

開始/終了の括弧がないので、Python はコーディングスタイルの対立が非常に
起こりにくくなります。C では多様なカッコの置き方があります。一つのスタ
イルでのコードの読み書きに慣れてしまうと、他のスタイルを読む (あるいは
書く必要がある) ときにむずむずするでしょう。

多くのコーディングスタイルは begin/end の括弧にそれぞれ一行を使います
。これではプログラムは冗長になって画面を浪費し、プログラムの見通しが悪
くなります。一つの関数は一画面 (例えば 20 から 30 行) に収めるのが理想
です。20 行の Python は 20 行の C よりもはるかに多くの作業ができます。
これは begin/end の括弧がないからだけではありません – 宣言が不要なこと
や高レベルなデータ型もその理由です – が、インデントに基づく構文は確か
に役に立っています。


なぜ単純な算術演算が奇妙な結果になるのですか？
==============================================

次の質問を参照してください。


Why are floating point calculations so inaccurate?
==================================================

People are often very surprised by results like this:

   >>> 1.2 - 1.0
   0.19999999999999996

and think it is a bug in Python. It’s not.  This has nothing to do
with Python, but with how the underlying C platform handles floating
point numbers, and ultimately with the inaccuracies introduced when
writing down numbers as a string of a fixed number of digits.

The internal representation of floating point numbers uses a fixed
number of binary digits to represent a decimal number.  Some decimal
numbers can’t be represented exactly in binary, resulting in small
roundoff errors.

In decimal math, there are many numbers that can’t be represented with
a fixed number of decimal digits, e.g.  1/3 = 0.3333333333…….

In base 2, 1/2 = 0.1, 1/4 = 0.01, 1/8 = 0.001, etc.  .2 equals 2/10
equals 1/5, resulting in the binary fractional number
0.001100110011001…

Floating point numbers only have 32 or 64 bits of precision, so the
digits are cut off at some point, and the resulting number is
0.199999999999999996 in decimal, not 0.2.

A floating point number’s "repr()" function prints as many digits are
necessary to make "eval(repr(f)) == f" true for any float f.  The
"str()" function prints fewer digits and this often results in the
more sensible number that was probably intended:

   >>> 1.1 - 0.9
   0.20000000000000007
   >>> print 1.1 - 0.9
   0.2

One of the consequences of this is that it is error-prone to compare
the result of some computation to a float with "==". Tiny inaccuracies
may mean that "==" fails.  Instead, you have to check that the
difference between the two numbers is less than a certain threshold:

   epsilon = 0.0000000000001  # Tiny allowed error
   expected_result = 0.4

   if expected_result-epsilon <= computation() <= expected_result+epsilon:
       ...

Please see the chapter on floating point arithmetic in the Python
tutorial for more information.


なぜ Python の文字列はイミュータブルなのですか？
================================================

これにはいくつかの利点があります。

一つはパフォーマンスです。文字列がイミュータブルなら、生成時に領域を割
り当てることができるので、必要な記憶域は固定されて、変更されません。こ
れはタプルとリストを区別する理由の一つでもあります。

他の利点は、Python の文字列は数と同じくらい 「基本的」 なものと考えら
れることです。8 という値を他の何かに変える手段が無いように、文字列 「
eight」 を他の何かに変える手段も無いのです。


なぜメソッドの定義や呼び出しにおいて 『self』 を明示しなければならないのですか？
================================================================================

このアイデアは Modula-3 から取り入れられました。これは様々な理由からと
ても便利だと言えます。

まず、ローカル変数ではなく、メソッドやインスタンス属性を扱っていること
がより明確になります。 "self.x" や "self.meth()" と書いてあれば、その
クラスの定義を憶えていなくても、それがインスタンス変数やメソッドである
ことは明らかです。C++ では、(グローバルが滅多になかったり、簡単に見分
けがつくなら) ローカル変数宣言がないことからある程度わかるでしょう。–
しかし Python にはローカル変数宣言がないので、クラス定義を調べて確かめ
なくてはなりません。C++ や Java のコーディングスタンダードに、インスタ
ンス属性に "m_" 接頭辞をつけるものがあるので、この明示性はそれらの言語
においても有用です。

第二に、特定のクラスからメソッドを明示的に参照または呼び出ししたい時に
、特別な構文が必要なくなります。C++ では、派生クラスでオーバーライドさ
れた基底クラスからメソッドを使うには、 "::" 演算子を使わなければなりま
せん。 – Python では、 "baseclass.methodname(self, <argument list>)"
と書けます。これは特に、 "__init__()" メソッドに便利ですし、派生クラス
のメソッドが、基底クラスにある同じ名前のメソッドを拡張するために、基底
クラスのメソッドをどうにかして呼び出したい時にも便利です。

最後に、インスタンス変数に対する、代入の構文の問題を解決できます。
Python のローカル変数は、関数の中で (global が明示的に宣言されることな
く) 値が代入された変数 (と定義されています！) です。なので、ある代入が
意図するのが、ローカル変数へではなくインスタンス変数への代入であると、
インタプリタが判断する手段が必要です。そしてそれは構文を見るだけで分か
る方が (効率が) 良いのです。C++ ではその区別を宣言時に行いますが、
Python では宣言がないので、この方法でしか区別できなかったら残念です。
"self.var" を明示すればうまく解決できます。同様に、インスタンス変数を
使うのにも "self.var" と書かなければならないので、メソッドの中の self
が付いていない名前への参照は、そのインスタンスのディレクトリを検索する
までもなくローカル変数とわかります。別の言い方をすれば、ローカル変数と
インスタンス変数は二つの異なる名前空間に存在し、Python にどちらの名前
空間を使うかを伝えなくてはならないのです。


式中で代入ができないのはなぜですか？
====================================

C や Perl に慣れた多くの人は、C のこの慣用句を使いたいと訴えます:

   while (line = readline(f)) {
       // do something with line
   }

Python ではこう書かなくてはなりません:

   while True:
       line = f.readline()
       if not line:
           break
       ...  # do something with line

Python の式中での代入を許さない理由は、この構造によって起こる、他の言
語ではありがちで見つけづらいバグです:

   if (x = 0) {
       // error handling
   }
   else {
       // code that only works for nonzero x
   }

このエラーは単純なタイプミスで、本当にやりたかったのは "x == 0" の比較
ですが、 "x = 0" と書いてしまい、変数 "x" に 0 を代入しています。

提案された代替案はたくさんあります。多くの案はタイプ数を少し節約します
が、勝手だったり意味不明だったりする構文や予約語を使い、言語変更の提案
の簡潔さの基準を満たしていません。構造の説明をされていない人間の読者に
、正しい意味を直感的に示す物であるべきです。

面白いことに、熟練した Python プログラマは "while True" イディオムを受
け入れていて、式構造中の代入がなくてもそれほど苦労しないようです。
Python にそれを強く求めるのは新人だけです。

以下の方法でもこれを綴ることができて、魅力的そうですが、堅牢さでは 「
while True」 を使う方法に劣ることが多いです:

   line = f.readline()
   while line:
       ...  # do something with line...
       line = f.readline()

この方法の問題は、次の行を取得する方法を変えたくなったとき
("sys.stdin.readline()" に変更したい時など) にプログラムの二箇所を変え
なくてはならないことです – 二つ目の場所はループの最後に隠れています。

The best approach is to use iterators, making it possible to loop
through objects using the "for" statement.  For example, in the
current version of Python file objects support the iterator protocol,
so you can now write simply:

   for line in f:
       ...  # do something with line...


Python にメソッドを使う機能 (list.index() 等) と関数を使う機能 (len(list) 等) があるのはなぜですか？
====================================================================================================

主な理由は歴史です。複数の型に対しての総称的な操作で、対象のオブジェク
トがメソッドを全く持っていなかった (例えば、タプル) としても働くよう意
図したものに関数は使われました。Python の関数的機能 ("map()" 、"zip()"
など) を使うときに、型のはっきりしないオブジェクトのコレクションに対し
て、難なく適用できる関数があるのも便利なことです。

実際、 "len()" 、 "max()" 、 "min()" を組み込み関数として実装すること
で、それぞれの型のメソッドとして実装するより少ないコードで済みます。個
々のケースについては粗探しのしようがありますが、Python の一部であるし
、根本的な変更をするには遅すぎます。これらの関数は、大規模なコードの破
壊を避けるために残す必要があります。

注釈: Python の文字列演算は、外部の関数 ("string" モジュール) からメ
  ソッド に移行しました。しかし、 "len()" は関数のままです。


join() がリストやタプルのメソッドではなく文字列のメソッドなのはなぜですか？
===========================================================================

文字列は Python 1.6 から他の標準型に大きく近づきました。それ以前は常に
string モジュールの関数を使ってできていたことと同等の機能を持つメソッ
ドがこの時に追加されました。その新しいメソッドの多くは広く受け入れられ
ましたが、一部のプログラマに不快を感じさせていると思われるものがこれで
:

   ", ".join(['1', '2', '4', '8', '16'])

結果はこうなります:

   "1, 2, 4, 8, 16"

この使い方には二つの議論があります。

一つ目は、「文字列リテラル (文字列定数) のメソッドを使うのは醜すぎる」
というようなものです。確かにそうかも知れませんが、文字列リテラルは単な
る固定された値に過ぎないというのが答えです。文字列に束縛された名前にメ
ソッドが許されるなら、リテラルに使えないようにする論理的な理由はないで
しょう。

二つ目の反対理由は、典型的には「私は実際、要素を文字列定数とともに結合
させるよう、シーケンスに命じているのだ」というものです。残念ながら、そ
うではないのです。いくつかの理由から "split()" を文字列のメソッドとし
ておいた方がはるかに簡単です。これを見ると分かりやすいでしょう

   "1, 2, 4, 8, 16".split(", ")

is an instruction to a string literal to return the substrings
delimited by the given separator (or, by default, arbitrary runs of
white space).  In this case a Unicode string returns a list of Unicode
strings, an ASCII string returns a list of ASCII strings, and everyone
is happy.

"join()" is a string method because in using it you are telling the
separator string to iterate over a sequence of strings and insert
itself between adjacent elements.  This method can be used with any
argument which obeys the rules for sequence objects, including any new
classes you might define yourself.

Because this is a string method it can work for Unicode strings as
well as plain ASCII strings.  If "join()" were a method of the
sequence types then the sequence types would have to decide which type
of string to return depending on the type of the separator.

If none of these arguments persuade you, then for the moment you can
continue to use the "join()" function from the string module, which
allows you to write

   string.join(['1', '2', '4', '8', '16'], ", ")


例外はどれくらい速いのですか？
==============================

try/except ブロックは例外が送出されなければ極端に効率的です。実際に例
外を捕捉するのは高価です。Python 2.0 より前のバージョンでは、このイデ
ィオムを使うのが一般的でした:

   try:
       value = mydict[key]
   except KeyError:
       mydict[key] = getvalue(key)
       value = mydict[key]

これは、辞書がほとんどの場合にキーを持っていると予想できるときにのみ意
味をなします。そうでなければ、このように書きます:

   if key in mydict:
       value = mydict[key]
   else:
       value = mydict[key] = getvalue(key)

注釈: In Python 2.0 and higher, you can code this as "value =
  mydict.setdefault(key, getvalue(key))".


Python に switch や case 文がないのはなぜですか？
=================================================

"if... elif... elif... else" の繰り返しで簡単に同じことができます。
switch 文の構文に関する提案がいくつかありましたが、範囲判定をするべき
か、あるいはどのようにするべきかについての合意は (まだ) 得られていませ
ん。現在の状況の完全な詳細は **PEP 275** を参照してください。

非常に大きな数の選択肢から選ぶとき、値を呼び出す関数に対応づける辞書を
作れます。例えば:

   def function_1(...):
       ...

   functions = {'a': function_1,
                'b': function_2,
                'c': self.method_1, ...}

   func = functions[value]
   func()

オブジェクトのメソッドを呼び出すには、さらに単純に "getattr()" 組み込
み関数で特定の名前のメソッドを検索できます:

   def visit_a(self, ...):
       ...
   ...

   def dispatch(self, value):
       method_name = 'visit_' + str(value)
       method = getattr(self, method_name)
       method()

メソッドの名前にこの例の "visit_" のような接頭辞を使うことを勧めます。
このような接頭辞がないと、信頼できないソースから値が与えられたときに、
オブジェクトの任意のメソッドを呼び出す攻撃をされる可能性があります。


OS 特有のスレッド実装に依らずにインタプリタでスレッドをエミュレートすることはできないのですか？
===============================================================================================

答 1: 残念なことに、インタプリタは Python のスタックフレームごとに少な
くとも一つの C のスタックフレームを push します。同様に、拡張もほとん
どランダムなときに Python にコールバックすることがあります。よって、完
全なスレッド実装には C のスレッドサポートが必要です。

答 2: 幸運なことに、完全に再設計された C スタックを使わないインタプリ
タループを持つ、 Stackless Python があります。


なぜラムダ式は文を含むことができないのですか?
=============================================

Python のラムダ式が文を含むことができないのは、Python の文法的な枠組み
が式の中にネストされた文を扱うことができないからです。しかし、Python
では、これは深刻な問題ではありません。他の言語のラムダに機能が追加され
ているのと違い、Python のラムダは単なる、関数を定義するのが面倒すぎる
場合のための簡略な記法に過ぎないのです。

関数は既に Python の第一級オブジェクトで、ローカルスコープ内で宣言でき
ます。従って、ローカルで定義された関数ではなくラムダを使う利点は、関数
の名前を考える必要が無いことだけです – しかし、(ラムダ式が生み出すオブ
ジェクトと厳密に同じ型の) 関数オブジェクトが代入される先はただのローカ
ル変数です！


Python は C やその他の言語のように機械語にコンパイルできますか？
================================================================

Cython は オプションのアノテーション付きのPythonの修正版を C拡張へ変換
します。Nuitka はPythonをC++コードへ変換する将来有望なPythonコンパイラ
で、完全なPython言語をサポートすることを目的としています。Javaへコンパ
イラするには、 VOC を検討してください。


Python はメモリをどのように管理するのですか？
=============================================

The details of Python memory management depend on the implementation.
The standard C implementation of Python uses reference counting to
detect inaccessible objects, and another mechanism to collect
reference cycles, periodically executing a cycle detection algorithm
which looks for inaccessible cycles and deletes the objects involved.
The "gc" module provides functions to perform a garbage collection,
obtain debugging statistics, and tune the collector’s parameters.

Jython relies on the Java runtime so the JVM’s garbage collector is
used.  This difference can cause some subtle porting problems if your
Python code depends on the behavior of the reference counting
implementation.

Sometimes objects get stuck in tracebacks temporarily and hence are
not deallocated when you might expect.  Clear the tracebacks with:

   import sys
   sys.exc_clear()
   sys.exc_traceback = sys.last_traceback = None

Tracebacks are used for reporting errors, implementing debuggers and
related things.  They contain a portion of the program state extracted
during the handling of an exception (usually the most recent
exception).

In the absence of circularities and tracebacks, Python programs do not
need to manage memory explicitly.

Why doesn’t Python use a more traditional garbage collection scheme?
For one thing, this is not a C standard feature and hence it’s not
portable.  (Yes, we know about the Boehm GC library.  It has bits of
assembler code for *most* common platforms, not for all of them, and
although it is mostly transparent, it isn’t completely transparent;
patches are required to get Python to work with it.)

Traditional GC also becomes a problem when Python is embedded into
other applications.  While in a standalone Python it’s fine to replace
the standard malloc() and free() with versions provided by the GC
library, an application embedding Python may want to have its *own*
substitute for malloc() and free(), and may not want Python’s.  Right
now, Python works with anything that implements malloc() and free()
properly.

In Jython, the following code (which is fine in CPython) will probably
run out of file descriptors long before it runs out of memory:

   for file in very_long_list_of_files:
       f = open(file)
       c = f.read(1)

Using the current reference counting and destructor scheme, each new
assignment to f closes the previous file.  Using GC, this is not
guaranteed.  If you want to write code that will work with any Python
implementation, you should explicitly close the file or use the "with"
statement; this will work regardless of GC:

   for file in very_long_list_of_files:
       with open(file) as f:
           c = f.read(1)


Why isn’t all memory freed when Python exits?
=============================================

Python モジュールのグローバルな名前空間から参照されるオブジェクトは、
Python の終了時にメモリの割り当てを解除されるとは限りません。これは、
循環参照があるときに起こりえます。解放できない C ライブラリ (例えば、
Purify のようなツールなどが当てはまります) によって割り当てられたいく
らかのメモリも含まれます。しかし、Python は終了時にメモリをクリーンア
ップすることには積極的で、全ての単一のオブジェクトを破棄しようとします
。

再割り当て時に Python が特定のものを削除するように強制したいときは、
"atexit" モジュールを使って削除を強制する関数を実行してください。


なぜタプルとリストという別のデータ型が用意されているのですか？
==============================================================

リストとタプルは、多くの点で似ていますが、一般には本質的に異なる方法で
使われます。タプルは、Pascal のレコードや C の構造体と同様なものと考え
られます。型が異なっても良い関連するデータの小さな集合で、グループとし
て演算されます。例えば、デカルト座標は 2 つや 3 つの数のタプルとして適
切に表せます。

一方、リストは、もっと他の言語の配列に近いものです。全て同じ型の可変数
のオブジェクトを持ち、それらが一つ一つ演算される傾向にあります。例えば
、 "os.listdir('.')" はカレントディレクトリ内にあるファイルの文字列表
現のリストを返します。この出力を演算する関数は一般に、ディレクトリに一
つや二つの別のファイルを加えても壊れません。

タプルはイミュータブルなので、一度タプルが生成されたら、そのどの要素も
新しい値に置き換えられません。リストはミュータブルなので、リストの要素
はいつでも変更できます。イミュータブルな要素だけが辞書のキーとして使え
るので、リストではなくタプルだけがキーとして使えます。


リストはどのように実装されているのですか？
==========================================

Python のリストは真の可変長配列であり、Lisp スタイルの連結リストではあ
りません。この実装は、他のオブジェクトへの参照の連続した配列を使い、リ
ストの頭部構造にこの配列へのポインタと配列の長さを保持します。

これにより、リストのインデクシング "a[i]" は、リストの大きさやインデク
スの値に依存しないコストで演算できます。

要素が追加または挿入されるとき、この参照の配列は大きさが変更されます。
要素追加の繰り返しのパフォーマンスを上げるために、少し工夫されています
。配列が大きくなるとき、次の何回かは実際に大きさを変更する必要がないよ
うに、いくらかの追加の領域が割り当てられます。


辞書はどのように実装されているのですか？
========================================

Python の辞書は大きさを変更できるハッシュテーブルとして実装されていま
す。 B 木と比べて、ほとんどの条件下で (特に一般的な演算である) 探索の
パフォーマンスが良いですし、実装も単純です。

Dictionaries work by computing a hash code for each key stored in the
dictionary using the "hash()" built-in function.  The hash code varies
widely depending on the key; for example, 「Python」 hashes to
-539294296 while 「python」, a string that differs by a single bit,
hashes to 1142331976.  The hash code is then used to calculate a
location in an internal array where the value will be stored. Assuming
that you’re storing keys that all have different hash values, this
means that dictionaries take constant time – O(1), in computer science
notation – to retrieve a key.  It also means that no sorted order of
the keys is maintained, and traversing the array as the ".keys()" and
".items()" do will output the dictionary’s content in some arbitrary
jumbled order.


なぜ辞書のキーはイミュータブルでなくてはならないのですか？
==========================================================

辞書のハッシュテーブルの実装は、キーを見つけるために、キー値から計算さ
れたハッシュ値を使います。もしキーがミュータブルなオブジェクトだったら
、その値は変えられ、それによりハッシュ値も変わってしまいます。しかし、
キーオブジェクトを変更したのが何者であれ、値が辞書のキーとして使われて
いたと気付けないので、辞書の中のエントリを適切な場所に動かせません。そ
して、同じオブジェクトを探そうとしても、ハッシュ値が違うため見つかりま
せん。古い値を探そうとしても、そのハッシュバイナリから見つかるオブジェ
クトの値は異なるでしょうから、これも見つかりません。

リストでインデクシングされた辞書が必要なら、まず単純にリストをタプルに
変換してください。関数 "tuple(L)" は、リスト "L" と同じエントリのタプ
ルを生成します。タプルはイミュータブルなので、辞書のキーとして使えます
。

いくつかの受け入れられなかった提案:

* アドレス (オブジェクト ID) のハッシュリスト。これは、同じ値の新し
  い リストを作っても見つからないので駄目です。例えば:

     mydict = {[1, 2]: '12'}
     print mydict[[1, 2]]

  は、2 行目の "[1, 2]" の id が 1 行目のものと違うため、 KeyError 例
  外を起こします。要するに、辞書のキーは "is" ではなく、 "==" で比較さ
  れるべきです。

* リストをキーとして使うときにコピーを作る。リストはミュータブルなの
  で 、自分自身への参照を含むことができ、コードをコピーするときに無限
  ルー プにハマる可能性があるので、これは駄目です。

* リストをキーとして使うことを認めるが、ユーザにそれを変更させないよ
  う に伝える。もしユーザが忘れたり、偶然にリストが変更されてしまった
  りし たら、追跡困難なバグの可能性を生じてしまいます。またこれは、
  "d.keys()" のすべての値は辞書のキーとして使えるという、辞書の重要な
  不変性も潰してしまいます。

* リストが一旦辞書のキーとして使われたら、読み込み専用のマークを付け
  る 。問題は、値を変えられるのはトップレベルオブジェクトだけではない
  こと です。リストを含むタプルもキーとして使えます。全てを辞書のキー
  として 導入すると、そこから到達可能な全てのオブジェクトに読み込み専
  用のマー クを付ける必要があります – そして再び、自己参照オブジェクト
  が無限ル ープを引き起こします。

必要ならばこれを回避する方法がありますが、自己責任のもとで行ってくださ
い。ミュータブルな構造を、 "__eq__()" と "__hash__()" メソッドの両方を
持つクラスインスタンスに含めることができます。その時、辞書 (またはハッ
シュに基づく別の構造体) に属するような全てのラッパーオブジェクトのハッ
シュ値が、そのオブジェクトが辞書 (その他の構造体) 中にある間固定され続
けることを確実にしてください。

   class ListWrapper:
       def __init__(self, the_list):
           self.the_list = the_list

       def __eq__(self, other):
           return self.the_list == other.the_list

       def __hash__(self):
           l = self.the_list
           result = 98767 - len(l)*555
           for i, el in enumerate(l):
               try:
                   result = result + (hash(el) % 9999999) * 1001 + i
               except Exception:
                   result = (result % 7777777) + i * 333
           return result

なお、リストのメンバーの中にハッシュ化できないものがある可能性や、算術
オーバーフローの可能性から、ハッシュ計算は複雑になります。

さらに、そのオブジェクトが辞書に含まれるか否かにかかわらず、 "o1 ==
o2" (すなわち "o1.__eq__(o2) is True") ならばいつでも "hash(o1) ==
hash(o2)" (すなわち "o1.__hash__() == o2.__hash__()") でなくてはなりま
せん。その制限に適合できなければ、辞書やその他のハッシュに基づく構造体
は間違いを起こします。

この ListWrapper の例では、異常を避けるため、ラッパオブジェクトが辞書
内にある限りラップされたリストが変更されてはなりません。この条件と満た
せなかった時の結果について知恵を絞る覚悟がない限り、これをしてはいけま
せん。よく考えてください。


なぜ list.sort() はソートされたリストを返さないのですか？
=========================================================

パフォーマンスが問題となる状況では、ソートするためだけにリストのコピー
を作るのは無駄が多いです。そこで、 "list.sort()" はインプレースにリス
トをソートします。このことを忘れないため、この関数はソートされたリスト
を返しません。こうすることで、ソートされたコピーが必要で、ソートされて
いないものも残しておきたいときに、うっかり上書きしてしまうようなことが
なくなります。

In Python 2.4 a new built-in function – "sorted()" – has been added.
This function creates a new list from a provided iterable, sorts it
and returns it.  For example, here’s how to iterate over the keys of a
dictionary in sorted order:

   for key in sorted(mydict):
       ...  # do whatever with mydict[key]...


Python ではどのようにインタフェース仕様を特定し適用するのですか？
=================================================================

C++ や Java のような言語が提供するような、モジュールに対するインタフェ
ース仕様の特定は、モジュールのメソッドや関数の原型を表現します。インタ
フェースの特定がコンパイル時に適用されることが、大きなプログラムの構成
に役立つと、広く感じられています。

Python 2.6 adds an "abc" module that lets you define Abstract Base
Classes (ABCs).  You can then use "isinstance()" and "issubclass()" to
check whether an instance or a class implements a particular ABC.  The
"collections" module defines a set of useful ABCs such as "Iterable",
"Container", and "MutableMapping".

Python では、コンポーネントの適切なテスト規律によって、インタフェース
仕様の多くの強みを活かせます。サブクラス化による問題を見つけるために使
えるツール PyChecker もあります。

モジュールのための適切なテストスイートは、回帰テストを提供し、モジュー
ルのインタフェース仕様や用例集としても役立ちます。多くの Python モジュ
ールは、簡単な「自己テスト」を提供するスクリプトとして実行できます。複
雑な外部インタフェースを使うモジュールさえ、外部インタフェースの細かい
「スタブ」エミュレーションで単独にテストできることが多いです。
"doctest" や "unittest" モジュール、あるいはサードパーティのテストフレ
ームワークで、モジュールのコードの全ての行に及ぶ徹底的なテストスイート
を構成できます。

Python で大きくて複雑なアプリケーションを構築するとき、インタフェース
仕様と同様に、適切なテスト規律も役立ちます。実際には、インタフェース仕
様ではテストできないプログラムの属性もあるので、それ以上にもなりえます
。例えば、 "append()" メソッドは新しい要素をある内部リストの終わりに加
えます。インタフェース仕様ではこの "append()" の実装が実際にこれを行う
かをテストできませんが、テストスイートならこの機能を簡単に確かめられま
す。

テストスイートを書くことはとても役に立ちますし、テストのしやすさという
視点でコードを設計することにもつながります。テスト指向開発は、人気を増
しつつある技法で、実際のコードを書き始める前に、最初からテストスイート
の部品を書くことを求めます。もちろん、 Python で粗雑にテストケースを全
く書かないこともできます。


なぜ goto が無いのですか？
==========================

関数の呼び出しをまたいでも動作する 「構造化された goto」 をまかなうも
のとして例外を使えます。C、Fortran、その他の言語での 「go」 あるいは
「goto」 構造の適切な用途は全て、例外で同じようなことををすれば便利で
あると、広く感じられています。例えば:

   class label: pass  # declare a label

   try:
       ...
       if condition: raise label()  # goto label
       ...
   except label:  # where to goto
       pass
   ...

例外ではループ内へ跳ぶことはできませんが、どちらにしてもそれは goto の
乱用と見なされるものです。使うのは控えてください。


なぜ raw 文字列 (r-strings) はバックスラッシュで終わってはいけないのですか？
============================================================================

正確には、奇数個のバックスラッシュで終わってはいけません。終わりの対に
なっていないバックスラッシュは、閉じ引用文字をエスケープし、終っていな
い文字列を残してしまいます。

raw 文字列は、独自にバックスラッシュの処理をしようとするプロセッサ (主
に正規表現エンジン) への入力を生成しやすいように設計されたものです。こ
のようなプロセッサは、終端の対になっていないバックスラッシュを結局エラ
ーとみなすので、raw 文字列はそれを認めません。その代わりに、バックスラ
ッシュでエスケープすることで、引用文字を文字列として渡すことができます
。r-string が意図された目的に使われるときに、この規則が役に立つのです
。

Windows のパス名を構築するときには、Windows のシステムコールは普通のス
ラッシュも受け付けることを憶えておいてください:

   f = open("/mydir/file.txt")  # works fine!

DOS コマンドのパス名を構築するときには、例えばこの中のどれかを試してく
ださい:

   dir = r"\this\is\my\dos\dir" "\\"
   dir = r"\this\is\my\dos\dir\ "[:-1]
   dir = "\\this\\is\\my\\dos\\dir\\"


属性の代入に 「with」 文が使えないのはなぜですか？
==================================================

Python には、ブロックの実行を包む 『with』 文があり、ブロックに入ると
きとブロックから出るときに、コードを呼び出します。以下のような構造を持
つ言語があります:

   with obj:
       a = 1               # equivalent to obj.a = 1
       total = total + 1   # obj.total = obj.total + 1

Python では、このような構造は曖昧になるでしょう。

Object Pascal、Delphi、C++のような他の言語では、静的な型を使うので、曖
昧な方法でも、どのメンバに代入されているのか分かります。これが静的型付
けの要点です – コンパイラは *いつでも* コンパイル時にすべての変数のス
コープを知るのです。

Python は動的な型を使います。実行時にどの属性が参照されるか事前に分か
りません。動作中にメンバ属性が追加あるいは除去されるかもしれません。こ
れでは、単純に読むだけではどのアトリビュートが参照されているか分かりま
せん。ローカルなのか、グローバルなのか、メンバ属性なのか？

例えば、以下の不完全なコード片を考えましょう:

   def foo(a):
       with a:
           print x

このコード片では、」a」 は 「x」 というメンバ属性を持っていると仮定さ
れています。しかし、Python ではインタプリタにはこの仮定を伝えられる仕
組みはありません。 「a」 が、例えば整数だったら、どうなってしまうでし
ょうか。 「x」 という名前のグローバル変数があったら、それが with ブロ
ックの中で使われるのでしょうか。この通り、Python の動的な特質から、こ
のような選択はとても難しい物になっています。

しかし、」with」 やそれに類する言語の機能の一番の利点 (コード量の削減)
は、 Python では代入により簡単に手に入れられます:

   function(args).mydict[index][index].a = 21
   function(args).mydict[index][index].b = 42
   function(args).mydict[index][index].c = 63

こう書いてください:

   ref = function(args).mydict[index][index]
   ref.a = 21
   ref.b = 42
   ref.c = 63

Python では実行時に名前束縛が解決され、後者はその解決が一度で済むため
、これには実行速度をあげる副作用もあります。


if/while/def/class 文にコロンが必要なのはなぜですか？
=====================================================

主に可読性を高めるため (実験的な ABC 言語の結果の一つ) に、コロンが必
要です:

   if a == b
       print a

と:

   if a == b:
       print a

を考えれば、後者のほうが少し読みやすいでしょう。さらに言えば、この FAQ
の解答例は次のようになるでしょう。これは、英語の標準的な用法です。

他の小さな理由は、コロンによってエディタがシンタックスハイライトをしや
すくなることです。プログラムテキストの手の込んだ解析をしなくても、コロ
ンを探せばいつインデントを増やすべきかを決められます。


なぜ Python ではリストやタプルの最後にカンマがあっても良いのですか？
====================================================================

Python では、リスト、タプル、辞書の最後の要素の後端にカンマをつけても
良いことになっています:

   [1, 2, 3,]
   ('a', 'b', 'c',)
   d = {
       "A": [1, 5],
       "B": [6, 7],  # last trailing comma is optional but good style
   }

これを許すのには、いくつかの理由があります。

リストやタプルや辞書のリテラルが複数行に渡っているときに、前の行にカン
マを追加するのを覚えておく必要が無いため、要素を追加するのが楽になりま
す。また、文法エラーを起こすこと無く、行の並べ替えを行うことができます
。

間違えてカンマを落としてしまうと、診断しづらいエラーにつながります。例
えば:

   x = [
     "fee",
     "fie"
     "foo",
     "fum"
   ]

このリストには4つの要素があるように見えますが、実際には3つしかありませ
ん。 「fee」、」fiefoo」、」fum」 です。 常にカンマを付けるようにすれ
ば、この種のエラーが避けられます。

後端にカンマをつけても良いことにすれば、プログラムによるコード生成も簡
単になります。
