デザインと歴史 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 のような多くの一般的な言語と同じように振る舞います。

10 進数で簡単に書ける多くの数が、2 進浮動小数点数では正確に表すことができません。例えばこうすると:

>>> x = 1.2

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

1.0011001100110011001100110011001100110011001100110011 (binary)

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

1.1999999999999999555910790149937383830547332763671875 (decimal)

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

詳しくは、Python チュートリアルの floating point arithmetic の章を参照してください。

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

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

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

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

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

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

まず、ローカル変数ではなく、メソッドやインスタンス属性を扱っていることがより明確になります。 self.xself.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/004643.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 文がないのはなぜですか?

In general, structured switch statements execute one block of code when an expression has a particular value or set of values. Since Python 3.10 one can easily match literal values, or constants within a namespace, with a match ... case statement. An older alternative is a sequence of 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_ のような接頭辞を使うことを勧めます。このような接頭辞がないと、信頼できないソースから値が与えられたときに、オブジェクトの任意のメソッドを呼び出す攻撃をされる可能性があります。

Imitating switch with fallthrough, as with C's switch-case-default, is possible, much harder, and less needed.

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

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

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

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

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

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

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

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

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

Python のメモリ管理の詳細は実装に依ります。Python の標準の C 実装 CPython は参照カウントを使って、アクセスできないオブジェクトを探します。また別のメカニズムを使って参照サイクルを集めます。これはサイクル検出アルゴリズムを定期的に実行し、アクセスできないサイクルを探し、巻き込まれたオブジェクトを削除します。 gc モジュールの関数で、ガベージコレクションを実行し、デバッグ統計を取得し、コレクタのパラメタを変更できます。

ただし、他の実装 (例えば JythonPyPy) は本格的 (full-blown) なガベージコレクタのような別のメカニズムに依存するかもしれません。あなたの Python コードが参照カウントの実装の振る舞いに依存する場合、この違いが微妙な移植上の問題を引き起こすでしょう。

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 モジュールでは、 IterableContainerMutableMapping などの便利な ABC が定義されています。

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

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

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

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