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


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

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

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

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

条件式が真のとき、 "x++" 行のみが実行されます。しかしインデントによっ
て、多くの人が別のことを考えてしまいます。経験豊富なCプログラマでさえ
、 "x > y" なのに "y" がデクリメントされるのはなぜだろうと、このコード
をしばらく凝視することがあります。

Python は開始/終了の括弧がないので、コーディングスタイルの争いに余り影
響されません。C言語では中括弧の置き方についてさまざまな流儀があります
。特定のスタイルを使ってコードを読み書きするのに慣れたあと、別のスタイ
ルでコードを読んだり(あるいは書く必要に迫られたり)するときに、何となく
心配になるのはよくあることです。

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


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

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


なぜ浮動小数点数の計算はこんなに不正確なんですか？
==================================================

ユーザーはよく次のような結果に驚きます:

   >>> 1.2 - 1.0
   0.19999999999999996

Python のバグと考えるかもしれませんが、そうではありません。  この結果
に Python はほとんど影響しておらず、むしろ大きく関係しているのは下敷き
としているプラットフォームによる浮動小数点数の扱い方です。

CPython における "float" 型は C 言語の "double" 型をデータ格納先に使い
ます。  "float" オブジェクトの値は固定精度 (典型的には 53 bit) の 2 進
浮動小数点数で格納されます。  そして Python は浮動小数点演算を行うため
に C の演算を使いますが、これはプロセッサのハードウェア実装に依存しま
す。つまり、浮動小数点数に関して Python は C 言語や Java を含む多くの
一般的な言語と同じように振る舞います。

Many numbers that can be written easily in decimal notation cannot be
expressed exactly in binary floating-point.  For example, after:

   >>> x = 1.2

"x" に保存された値は 10 進数の "1.2" の (とても高い精度の) 近似値であ
って、厳密な "1.2" ではありません。一般的なコンピューターでは、実際に
格納される値は:

   1.0011001100110011001100110011001100110011001100110011 (binary)

で、正確には次の値です:

   1.1999999999999999555910790149937383830547332763671875 (decimal)

典型的な 53bit 精度は、Python の float に 10 進数での 15〜16 桁の正確
さを与えます。

For a fuller explanation, please see the floating point arithmetic
chapter in the Python tutorial.


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

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

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

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


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

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

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

Second, it means that no special syntax is necessary if you want to
explicitly reference or call the method from a particular class.  In
C++, if you want to use a method from a base class which is overridden
in a derived class, you have to use the "::" operator -- in Python you
can write "baseclass.methodname(self, <argument list>)".  This is
particularly useful for "__init__()" methods, and in general in cases
where a derived class method wants to extend the base class method of
the same name and thus has to call the base class method somehow.

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


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

Python 3.8 以降ならできるよ!

セイウチ演算子 ":=" を使った代入式は、式の中で変数に代入します:

   while chunk := fp.read(200):
      print(chunk)

より詳しくは **PEP 572** を参照してください。


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

Guidoいわく：

   （a） 幾つかの演算では、接頭辞は接尾辞よりも単純に読みやすいからで
   す。接頭辞（そして接中辞！）による演算は数学において長い歴史があり
   、そこでは課題に対する数学者の思考を視覚的に助けるような記法が好ま
   れます。x*(a+b)をx*a + x*bに書き換える容易さと、それと同じことを純
   粋なオブジェクト指向の記法で行う煩わしさを比較してみてください。

   （b） len(x) というコードを読んだ時、私はそれが何かの長さを問うてい
   るのだなと知ることができます。これは私に2つの事を知らせています。一
   つは結果が整数であること、そして引数は何らかのコンテナであることで
   す。対して、 x.len() を目にした場合、私はその時点でxが何らかのコン
   テナであり、それが標準のlen()を持っているクラスを継承しているか、イ
   ンターフェースを実装していることを知っている必要があります。
   mapping を実装していないクラスが get() や keys() メソッドを持ってい
   たり、 file でない何かが write() メソッドを持っているような混乱は時
   折見かけます。

   -- https://mail.python.org/pipermail/python-3000/2006-November/004
   643.html


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

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

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

結果はこうなります:

   "1, 2, 4, 8, 16"

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

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

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

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

これは文字列リテラルに対する、与えられたセパレータ (または、デフォルト
では任意の空白文字の連続) で区切られた部分文字列を返せという指示です。

"join()" は、セパレータ文字列に、文字列のシーケンスをイテレートして隣
り合う要素の間に自身を挿入するように指示しているので、文字列のメソッド
です。このメソッドは、独自に定義された新しいクラスを含め、シーケンスの
規則を満たすいかなる引数にも使えます。バイト列やバイト配列にも同様のメ
ソッドがあります。


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

A try/except block is extremely efficient if no exceptions are raised.
Actually catching an exception is expensive.  In versions of Python
prior to 2.0 it was common to use this idiom:

   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)

この特殊な場合では "value = dict.setdefault(key, getvalue(key))" も使
えますが、これは "getvalue()" 呼び出しが十分安価な場合に限ります。なぜ
ならそれが全ての場合に評価されるからです。


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

一般的に、構造化された switch 文は、式が特定の値または値の集合を持つと
き、１つのコードブロックを実行します。 Python 3.10 以降では、リテラル
値や名前空間内の定数を、 "match ... case" 文で簡単にマッチさせることが
できます。より古い手段は一連の "if... elif... elif... else" です。

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

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

   func = functions[value]
   func()

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

   class MyVisitor:
       def visit_a(self):
           ...

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

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

C の switch-case-default のような、フォールスルーのある switch を模倣
することもできますが、はるかに難しいうえに必要性も少ないでしょう。


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

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

答 2: 幸運なことに、Stackless Python があります。これは完全に再デザイ
ンされたインタープリタで、Cのスタックを回避しています。


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

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

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


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

Cython compiles a modified version of Python with optional annotations
into C extensions.  Nuitka is an up-and-coming compiler of Python into
C++ code, aiming to support the full Python language.


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

Python のメモリ管理の詳細は実装に依ります。  Python の標準実装である
*CPython* は、参照カウントを使ってアクセスできない（訳注：参照されえな
い）オブジェクトを検出し、そして別の仕組みで参照サイクル（循環参照）を
集めます。サイクル検出アルゴリズムを定期的に実行し、アクセスできないサ
イクルを見つけて一連のオブジェクトを削除します。 "gc" モジュールは、ガ
ベージコレクションの実行、デバッグ統計の取得、コレクタのパラメータ調整
を行う関数を提供します。

Other implementations (such as Jython or PyPy), however, can rely on a
different mechanism such as a full-blown garbage collector.  This
difference can cause some subtle porting problems if your Python code
depends on the behavior of the reference counting implementation.

Python の実装によっては、以下の (CPython では通る) コードはおそらく、
ファイルディスクリプタを使い果たすでしょう:

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

Indeed, using CPython's reference counting and destructor scheme, each
new assignment to *f* closes the previous file.  With a traditional
GC, however, those file objects will only get collected (and closed)
at varying and possibly long intervals.

Python の実装に依らずに動くコードを書くには、ファイルを明示的に閉じる
か、 "with" 文を使ってください。これでメモリ管理のスキームに関係なく動
きます:

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


CPython はなぜ伝統的なガベージコレクションスキームを使わないのですか？
======================================================================

まず、それは C の標準的な機能ではないのでポータブルではありません。(確
かに Boehm GC ライブラリはあります。しかし、これにはアセンブリコードが
含まれ、*ほとんどの* 有名なプラットフォームに対応していますが全てでは
ありません。また、ほとんど透過的ですが、完全に透過的ではありません。
Python を対応させるにはパッチが必要です。)

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, CPython works with anything that implements malloc() and free()
properly.


なぜ CPython の終了時にすべてのメモリが解放されるわけではないのですか？
=======================================================================

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

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


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

Lists and tuples, while similar in many respects, are generally used
in fundamentally different ways.  Tuples can be thought of as being
similar to Pascal records or C structs; they're small collections of
related data which may be of different types which are operated on as
a group.  For example, a Cartesian coordinate is appropriately
represented as a tuple of two or three numbers.

Lists, on the other hand, are more like arrays in other languages.
They tend to hold a varying number of objects all of which have the
same type and which are operated on one-by-one.  For example,
"os.listdir('.')" returns a list of strings representing the files in
the current directory.  Functions which operate on this output would
generally not break if you added another file or two to the directory.

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


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

CPythonのリストは実際に変数分の長さの配列で、Lispスタイルの連結リスト
ではありません。この実装は他のオブジェクトへの参照の連続した配列を使用
していて、この配列へのポインタおよび配列長はリストの先頭の構造体に保存
されています。

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

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


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

CPython の辞書は大きさを変更できるハッシュテーブルとして実装されていま
す。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 and a per-process seed; for example,
"Python" could hash to -539294296 while "python", a string that
differs by a single bit, could hash 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 Big-O notation -- to retrieve a key.


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

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

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

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

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

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

  "[1, 2]" の2行目のidは1行目のそれと異なってしまうために "KeyError"
  例外を送出するでしょう。言い換えれば、辞書のキーは "==" を使って比較
  されるべきであり、 "is" ではないということです。

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

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

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

There is a trick to get around this if you need to, but use it at your
own risk: You can wrap a mutable structure inside a class instance
which has both a "__eq__()" and a "__hash__()" method.  You must then
make sure that the hash value for all such wrapper objects that reside
in a dictionary (or other hash based structure), remain fixed while
the object is in the dictionary (or other structure).

   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__()") でなくてはなりま
せん。その制限に適合できなければ、辞書やその他のハッシュに基づく構造体
は間違いを起こします。

In the case of ListWrapper, whenever the wrapper object is in a
dictionary the wrapped list must not change to avoid anomalies.  Don't
do this unless you are prepared to think hard about the requirements
and the consequences of not meeting them correctly.  Consider yourself
warned.


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

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

新しいリストを返したいなら、代わりに組み込みの "sorted()" 関数を使って
ください。この関数は、与えられたイテレート可能オブジェクトから新しいリ
ストを生成し、ソートして返します。例えば、辞書のキーをソートされた順序
でイテレートする方法は:

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


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

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

Python 2.6 で、抽象基底クラス (Abstract Base Class, ABC) が定義できる
ようになる "abc" モジュールが追加されました。なので "isinstance()" と
"issubclass()" を使って、インスタンスやクラスが、ある ABC を実装してい
るかどうかチェックできます。"collections.abc" モジュールでは、
"Iterable" 、 "Container" 、 "MutableMapping" などの便利な ABC が定義
されています。

Pythonでは、インターフェース仕様の多くの利点は、コンポーネントへの適切
なテスト規律により得られます。

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

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

テストスイートを書くことはとても有用ですし、簡単にテストできるコード設
計を心がけると良いでしょう。人気を博している開発手法の一つ、テスト駆動
開発は、実際のコードを記述するよりも先に、まずテストスイートの部分を記
述するよう求めています。ご心配なく、Python は、あなたがいい加減でもテ
ストケースを全く書かなくても構いません。


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

In the 1970s people realized that unrestricted goto could lead to
messy "spaghetti" code that was hard to understand and revise. In a
high-level language, it is also unneeded as long as there are ways to
branch (in Python, with "if" statements and "or", "and", and "if-else"
expressions) and loop (with "while" and "for" statements, possibly
containing "continue" and "break").

One can also use exceptions to provide a "structured goto" that works
even across function calls.  Many feel that exceptions can
conveniently emulate all reasonable uses of the "go" or "goto"
constructs of C, Fortran, and other languages.  For example:

   class label(Exception): pass  # declare a label

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

This doesn't allow you to jump into the middle of a loop, but that's
usually considered an abuse of goto anyway.  Use sparingly.


なぜ 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 has a 'with' statement that wraps the execution of a block,
calling code on the entrance and exit from the block.  Some languages
have a construct that looks like this:

   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)

The snippet assumes that "a" must have a member attribute called "x".
However, there is nothing in Python that tells the interpreter this.
What should happen if "a" is, let us say, an integer?  If there is a
global variable named "x", will it be used inside the with block?  As
you see, the dynamic nature of Python makes such choices much harder.

The primary benefit of "with" and similar language features (reduction
of code volume) can, however, easily be achieved in Python by
assignment.  Instead of:

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


なぜジェネレータは with 文をサポートしないのですか？
====================================================

For technical reasons, a generator used directly as a context manager
would not work correctly.  When, as is most common, a generator is
used as an iterator run to completion, no closing is needed.  When it
is, wrap it as "contextlib.closing(generator)" in the 'with'
statement.


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" です。 常にカンマを付けるようにすれば、こ
の種のエラーが避けられます。

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