プログラミング FAQ
******************


一般的な質問
============


ブレークポイントやシングルステップ実行などを備えたソースコードレベルデバッガはありますか？
------------------------------------------------------------------------------------------

はい。

pdb モジュールは簡素にして十分な Python のコンソールモードデバッガです
。これは Python の標準ライブラリに含まれているもので、 "ライブラリリフ
ァレンスマニュアルにドキュメントがあります" 。 pdb のコードを手本にし
て自分用のデバッガを書くこともできます。

Python に同梱されている統合開発環境の IDLE は通常の Python の配布形態
の一部 (普通は Tools/scripts/idle から利用可能) であり、グラフィカルな
デバッガを含んでいます。

PythonWin は、pdb をベースとした GUI デバッガを含む Python IDE です。
Pythonwin デバッガは、ブレークポイントの色付けや非 Pythonwin プログラ
ムのデバッグなどのたくさんの素敵な機能を持っています。Pythonwin は
Python for Windows Extensions プロジェクトの一部、あるいは
ActivePython ディストリビューション
(https://www.activestate.com/activepython を参照) の一部として利用可能
です。

Boa Constructor は、wxWidgets を使った IDE と GUI ビルダーです。これは
視覚フレームの作成と操作、オブジェクト検査、オブジェクトブラウザのよう
な多くのビュー、継承構造、doc string から生成される html ドキュメント
、高度なデバッガ、総合ヘルプ、Zope のサポートを提供します。

Eric は PyQt や Scintilla editing component をもとにした IDE です。

Pydb は標準のデバッガである pdb を人気のグラフィカルデバッガフロントエ
ンドである DDD (Data Display Debugger) とともに使うために改変したもの
です。Pydb は http://bashdb.sourceforge.net/pydb/ に、 DDD は
https://www.gnu.org/software/ddd にあります。

商業のグラフィカルデバッガ付き Python IDE もあります。例えば:

* Wing IDE (https://wingware.com/)

* Komodo IDE (https://komodoide.com/)

* PyCharm (https://www.jetbrains.com/pycharm/)


バグの発見や静的分析に役立つツールはありますか？
------------------------------------------------

はい。

PyChecker は Python ソースコードのバグを発見しコードの複雑さとスタイル
について警告する静的解析ツールです。PyChecker は
http://pychecker.sourceforge.net/ から手に入ります。

Pylint も、モジュールがコーディング標準を満たすかを調べ、プラグインを
書いてカスタム機能を加えられるようにするツールです。PyChecker が行うバ
グチェックに加え、 Pylint は行の長さ、変数名が一貫しているか、宣言され
たインタフェースが完全に実装されているか、などを確かめる追加の機能を提
供します。 https://docs.pylint.org/ で Pylint の機能の一覧を見られます
。


どうしたら Python スクリプトからスタンドアロンバイナリを作れますか？
--------------------------------------------------------------------

ユーザがダウンロードや起動のために Python ディストリビューションをイン
ストールしなくてもよいスタンドアロンプログラムのためだけなら、Python
を C コードにコンパイルできる必要はありません。プログラムに対して必要
なモジュールを選び、そのモジュールを Python バイナリに束縛して一つの実
行可能ファイルにまとめる多くのツールがあります。

一つは freeze ツールで、Python ソースツリーに "Tools/freeze" として含
まれています。これは Python バイトコードを C 配列に変換します。すべて
のモジュールを標準 Python モジュールにリンクされる新しいプログラムに埋
め込む C コンパイラです。

これはあなたのソースの (両方の形式の) import 文を再帰的にスキャンして
、import されたモジュールを標準の Python パスと (組み込みモジュールの
ある) ソースディレクトリから探します。そして Python で書かれたモジュー
ルのバイトコードを C コード (marshal モジュールでコードオブジェクトに
変換できる配列) に変換し、実際にそのプログラム内で使われている組み込み
モジュールだけが含まれたカスタムメイドの設定ファイルを作成します。そし
て生成された C コードをコンパイルして Python インタプリタの残りとリン
クし、元のスクリプトと全く同じように動作する自己充足的なバイナリを形成
します。

もちろん、凍結には C コンパイラが必要です。C コンパイラを必要としない
選択肢もあります。その一つは、Thomas Heller の py2exe (Windows 専用)
です

   http://www.py2exe.org/

他には Anthony Tuininga の cx_Freeze があります。


Python プログラムのためのコーディングスタンダードやスタイルガイドはありますか？
-------------------------------------------------------------------------------

はい。標準ライブラリモジュールに求められるコーディングスタイルは **PEP
8** として文書化されています。


プログラムが遅すぎます。どうしたら速くなりますか？
--------------------------------------------------

一般に、それは難しい質問です。Python コードを速くするためには、いろい
ろな手法があります。最終手段として一部を C で書き直す事も考えてくださ
い。

Python を自動的に C や x86 アセンブリ言語に変換できる場合もあります。
この場合、速度を上げるためにコードを変更する必要はありません。

Pyrex はPython コードの少し変化した版を C 拡張にコンパイルでき、多様な
プラットフォームで使えます。(訳注： Pyrex は Cython に取って代わられて
います。)

Psyco は Python コードを x86 アセンブリ言語に変換する実行時コンパイラ
です。これを使うことが出来れば、重要な関数を劇的にスピードアップできま
す。

あとは、Python コードからもう少し速度を搾り出すための様々な手法につい
て議論することになります。コード中の特定の関数が処理が集中するホットス
ポットで、最適化が必要であると認められない限り、*決して* いかなる最適
化の手法も使わないでください。最適化はたいていコードを分かりづらくする
ので、分かりづらさのコスト (開発時間の延長とバグの可能性の増大) がそれ
に見合ったパフォーマンスの向上につながらないのであれば元が取れません。

performance tips に関するページが wiki にあります。

Guido van Rossum は https://www.python.org/doc/essays/list2str で最適
化に関する逸話を詳述しています。

なお、関数や(特に)メソッドの呼び出しはかなり高価です。インスタンス変数
を get や set したり他のメソッドを呼び出す程度の小さな関数がたくさんあ
る純粋 OO インタフェースをデザインしているなら、インスタンス変数に直接
アクセスするようなもっと直接的な方法も考えてみてください。また、どのプ
ログラムが実行時間の大部分を占めているかを見つける標準モジュール
"profile" も参照してください (ちょっと忍耐できればの話ですが - プロフ
ァイリングはそれ自体がプログラムを一桁ほど遅くしてしまいます)。

もちろん、他のプログラミングの経験から得られた多くの標準的な最適化の発
見的手法は Python にもよく当てはまることが多いです。たとえば、出力装置
に出力を送るときに、一度に少なく書くよりもむしろ多く書いたほうが、カー
ネルのシステムコールのオーバーヘッドを減らすことができて、速くなるでし
ょう。したがって、CGI スクリプトは "一発" ですべて書き出すもののほうが
小さなたくさんの出力に分けて書き出すものよりも速くなるでしょう。

また、必ず Python のコアな機能を適切に使ってください。例えば、スライシ
ングなら、リストや他のシーケンスオブジェクトを、高度に最適化された C
実装で、インタプリタのメインループの一刻みで細切れにできます。こうして
効果を得ることができる例は:

   L2 = []
   for i in range(3):
       L2.append(L1[i])

こう使えばずっと短く、ずっと速くできます:

   L2 = list(L1[:3])  # "list" is redundant if L1 is a list.

関数指向組み込み関数 "map()" や "zip()" なども一つのタスクを実行するた
めのループを加速するのに便利であることに注意してください。例えば、二つ
のリストの要素を組み合わせるためには:

   >>> zip([1, 2, 3], [4, 5, 6])
   [(1, 4), (2, 5), (3, 6)]

また、正弦を一度に計算するには:

   >>> map(math.sin, (1, 2, 3, 4))
   [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308]

このような場合には素早く演算が完了します。

その他の例には、 文字列オブジェクトのメソッド "join()" 、 "split()" な
どが挙げられます。例えば s1..s7 が大きな (10K+) 文字列の時、
""".join([s1,s2,s3,s4,s5,s6,s7])" は単純に "s1+s2+s3+s4+s5+s6+s7" とす
るよりもはるかに速くなるでしょう。なぜなら、 "join()" はすべてのコピー
を一括して行うのに対し、「足し算」が多くの副演算を行うからです。文字列
を扱うには、 文字列オブジェクトのメソッド "replace()" 、 "format()"
を使ってください。正規表現を使うのは、決まった文字列のパターンを使わな
い時だけにしてください。 旧式の % 演算 "string % tuple" と "string %
dictionary" も使えます。

ソートには必ずビルトインオブジェクトの "list.sort()" を使ってください
。また、 sorting mini-HOWTO の少し高度な使い方の例を参照してください。
"list.sort()" は、よほど極端な状況でない限り、他のソートの技術に勝りま
す。

「ループを関数やメソッドの中に入れ込む」というのも一般的な手法です。例
えば、遅いプログラムがあって、Python の "ff()" 関数が何度も呼ばれてい
ることがプロファイラで分かったとします。この "ff()"

   def ff(x):
       ... # do something with x computing result...
       return result

がこのようなループで呼ばれる傾向がある気付いたとして:

   list = map(ff, oldlist)

もしくは:

   for x in sequence:
       value = ff(x)
       ... # do something with value...

"ff()" を書き換えて:

   def ffseq(seq):
       resultseq = []
       for x in seq:
           ... # do something with x computing result...
           resultseq.append(result)
       return resultseq

また、上の二つの例を、 "list = ffseq(oldlist)" と:

   for value in ffseq(sequence):
       ... # do something with value...

のように書き換えることによって、関数を呼ぶためのオーバーヘッドを省ける
ことが多いです。"ff(x)" を一回だけ呼ぶ場合、 "ffseq([x])[0]" に直して
しまうとちょっと不利になります。 もちろん、このテクニックがいつでも適
切であるわけではありませんし、解決のための他の方法もあります。

関数やメソッドの探索の結果をローカル変数に明示的に保存すると少しパフォ
ーマンスが良くなります。次のようなループ:

   for key in token:
       dict[key] = dict.get(key, 0) + 1

は、繰り返しのたびに "dict.get" を求めています。 このメソッドが変わる
ことがないのなら、少し速い実装は:

   dict_get = dict.get  # look up the method once
   for key in token:
       dict[key] = dict_get(key, 0) + 1

デフォルト引数は、実行時でなく、コンパイル時に値を一回で決めてしまうの
に使えます。これは、プログラムの実行中に変化しない関数やオブジェクト、
例えば:

   def degree_sin(deg):
       return math.sin(deg * math.pi / 180.0)

を、次のように置き換えるときにのみ行えます:

   def degree_sin(deg, factor=math.pi/180.0, sin=math.sin):
       return sin(deg * factor)

この手法はデフォルト引数が変えられないことを前提に使うので、ユーザーが
API で混乱するおそれがないときのみ使えます。


コア言語
========


なぜ変数に値があるのに UnboundLocalError が出るのですか？
---------------------------------------------------------

もともと動いていたコードが、関数の本体のどこかに代入文を加えるという変
更をしたら UnboundLocalError を出すのには驚くかもしれません。

このコード:

>>> x = 10
>>> def bar():
...     print x
>>> bar()
10

は動きますが、このコード:

>>> x = 10
>>> def foo():
...     print x
...     x += 1

は UnboundLocalError になります:

>>> foo()
Traceback (most recent call last):
  ...
UnboundLocalError: local variable 'x' referenced before assignment

これは、あるスコープの中で変数に代入を行うとき、その変数はそのスコープ
に対してローカルになり、外のスコープにある同じ名前の変数を隠すからです
。 foo の最後の文が "x" に新しい値を代入しているので、コンパイラはこれ
をローカル変数であると認識します。その結果、先の "print x" が初期化さ
れていないローカル変数を表示しようとして結果はエラーとなります。

上の例では、グローバルであると宣言することで外のスコープにアクセスでき
ます:

>>> x = 10
>>> def foobar():
...     global x
...     print x
...     x += 1
>>> foobar()
10

この明示的な宣言は (表面的には似ているクラスとインスタンス変数の例とは
違って) あなたは実際は他のスコープの変数の値を変えようとしているのだ、
ということを知らせるのに必要です:

>>> print x
11


Python のローカルとグローバル変数のルールは何ですか？
-----------------------------------------------------

Python では、関数の中で参照のみされる変数は暗黙のうちにグローバルにな
ります。関数の本体のどこかで値が変数に代入されたなら、それは明示的にグ
ローバルであると宣言されない限り、ローカルであるとみなされます。

最初はちょっと驚くでしょうが、少し考えると納得できます。一方では、代入
された変数に "global" を要求することで、意図しない副作用を防げます。他
方では、グローバルな参照の度に "global" が要求されてしまうと、
"global" を使ってばかりになってしまいます。ビルトイン関数やインポート
されたモジュールの内容を参照するたびにグローバル宣言をしなければならな
いのです。その乱雑さは副作用を特定するための "global" 宣言の便利さより
も重大です。


ループの中で異なる値で定義されたラムダ式が、同じ値を返すのはなぜですか？
------------------------------------------------------------------------

for ループを使って、少しずつ異なるラムダを定義 (もしくは簡単な関数) す
るとします。例えば:

   >>> squares = []
   >>> for x in range(5):
   ...     squares.append(lambda: x**2)

これで "x**2" を計算する 5 つのラムダのリストが得られます。それらを呼
び出したとき、それぞれ "0"、"1"、"4"、"9"、"16" を返すと予想するかもし
れません。しかし実際にやってみると、全て "16" が返ってくるのを目にする
でしょう:

   >>> squares[2]()
   16
   >>> squares[4]()
   16

これは、"x" がラムダにとってのローカル変数ではなく外側のスコープで定義
されていて、ラムダが定義されたときでなく呼び出されたときにアクセスされ
るために起こります。ループが終わった時点では "x" は "4" であり、従って
、全ての関数は "4**2" つまり "16" を返します。このことは "x" の値を変
えてみることで検証でき、ラムダの返り値がどのように変わるのか観察できま
す:

   >>> x = 8
   >>> squares[2]()
   64

これを避けるためには、グローバルの "x" の値に依存しないために、ラムダ
にとってのローカル変数に値を保存する必要があります:

   >>> squares = []
   >>> for x in range(5):
   ...     squares.append(lambda n=x: n**2)

ここで、"n=x" は新しいラムダにとってのローカル変数 "n" を作成し、ラム
ダが定義されるときに計算されるので、ループのその時点での "x" と同じ値
を持っています。これは、1 つ目のラムダでは "n" の値は "0" になり、2 つ
目では "1"、3 つ目では "2" 以下同様、となることを意味します。従って、
それぞれのラムダは今や正しい値を返すようになりました:

   >>> squares[2]()
   4
   >>> squares[4]()
   16

この動作はラムダに特有なものではなく、通常の関数にも適用されることに注
意してください。


グローバル変数をモジュール間で共有するにはどうしたらいいですか？
----------------------------------------------------------------

一つのプログラムのモジュール間で情報を共有する正準な方法は、特別なモジ
ュール (しばしば config や cfg と呼ばれる) を作ることです。単に設定モ
ジュールをアプリケーションのすべてのモジュールにインポートしてください
。このモジュールはグローバルな名前として使えます。それぞれのモジュール
のただ一つのインスタンスがあるので、設定モジュールオブジェクトに対する
いかなる変更も全体に反映されます。例えば:

config.py:

   x = 0   # Default value of the 'x' configuration setting

mod.py:

   import config
   config.x = 1

main.py:

   import config
   import mod
   print config.x

なお、同じ理由から、モジュールを使うということは、シングルトンデザイン
パターンを実装することの基礎でもあります。


モジュールで import を使う際の「ベストプラクティス」は何ですか？
----------------------------------------------------------------

一般的に "from modulename import *" を使ってはいけません。そのようにす
るとインポータの名前空間は汚染され、linter が未定義の名前を発見するこ
とが難しくなります。

モジュールはファイルの先頭でインポートしてください。これによってコード
が必要とする他のモジュールが明確になり、モジュール名がスコープに含まれ
るかどうかに迷わなくなります。行に一つのインポートにすると、モジュール
のインポートの追加と削除が容易になりますが、行に複数のインポートにする
と画面の領域が少なく済みます。

次の手順でモジュールをインポートするのが、良いプラクティスになります:

1. 標準ライブラリモジュール -- 例 "sys"、"os"、"getopt"、"re"

2. サードパーティのライブラリモジュール (Python の site-packages デ
   ィ レクトリにあるもの) -- 例 mx.DateTime、ZODB、PIL.Image、など

3. 自前で開発したモジュール

明示的な相対インポートだけを使ってください。 "package.sub.m1" モジュー
ルのコードを書いていて、 "package.sub.m2" をインポートしようとするとき
に "import m2" だけで済ませるのはやめてください。たとえそれが合法でも
。代わりに "from package.sub import m2" または "from . import m2" と書
いてください。

循環参照の問題を避けるために、インポートを関数やクラスに移すことが必要
なときもあります。Gordon McMillan によれば:

   循環参照は両方のモジュールが "import <module>" 形式のインポートを使
   っていれば大丈夫です。二つ目のモジュールが最初のモジュールから名前
   を確保しようとして ("from module import name")、そのインポートがト
   ップレベルにあると駄目です。最初のモジュールが二つ目のモジュールを
   インポートするのに忙しくて、最初のモジュールの名前が利用可能になっ
   ていないからです。

この状況では、二つ目のモジュールが一つの関数の中でのみ使われているなら
ば、そのインポートは簡単に関数の中に移せます。インポートが呼ばれたとき
、最初のモジュールは初期化を完了していて、二つ目のモジュールは自分のイ
ンポートをできます。

プラットフォーム依存のモジュールがあるときには、インポートをトップレベ
ルの外に動かすことも必要です。この場合、ファイルの先頭ではすべてのモジ
ュールをインポートすることさえできないかもしれません。この場合は、対応
するプラットフォームに合わせたコードで正しいモジュールをインポートする
ことを選ぶと良いです。

循環参照の問題を避けたりモジュールの初期化にかかる時間を減らしたりした
いなら、単にインポートを関数定義の中などのローカルなスコープに移してく
ださい。この手法は多くのインポートがプログラムがどのように実行されるか
に依存しなくてよいときに特に有効です。ある関数の中でのみモジュールが使
われるのなら、インポートをその関数の中に移すことを考えてもいいでしょう
。なお、モジュールを読み込む最初の回はモジュールの初期化の時間のために
高価になりえますが、複数回目にモジュールを読み込むのは事実上無料、辞書
探索の数回のコストだけで済みます。モジュール名がスコープから外れてさえ
、そのモジュールはおそらく "sys.modules" から利用できるでしょう。


なぜオブジェクト間でデフォルト値が共有されるのですか？
------------------------------------------------------

この種のバグがよく初心者プログラマに噛み付きます。この関数を考えてみて
ください:

   def foo(mydict={}):  # Danger: shared reference to one dict for all calls
       ... compute something ...
       mydict[key] = value
       return mydict

初めてこの関数を呼び出した時、"mydict" には一つの要素があります。二回
目には、"foo()" が実行されるときに "mydict" には初めから一つの要素をす
でに持っているので、"mydict" には二つの要素があります。

関数の呼び出しによって、デフォルトの値に対する新しいオブジェクトが作ら
れるのだと予想しがちです。実はそうなりません。デフォルト値は、関数が定
義されたときに一度だけ生成されます。この例の辞書のように、そのオブジェ
クトが変更されたとき、その後の関数の呼び出しは変更後のオブジェクトを参
照します。

定義の時に、数、文字列、タプル、"None" など、イミュータブルなオブジェ
クトを使うと変更される危険がありません。辞書、リスト、クラスインスタン
スなどのミュータブルなオブジェクトは混乱のもとです。

この性質から、ミュータブルなオブジェクトをデフォルト値として使わないプ
ログラミング手法がいいです。代わりに、"None" をデフォルト値に使い、そ
のパラメタが "None" である時にだけ、関数の内部で新しいリスト/辞書/その
他をつくるようにしてください。例えば、こう書かずに:

   def foo(mydict={}):
       ...

代わりに:

   def foo(mydict=None):
       if mydict is None:
           mydict = {}  # create a new dict for local namespace

この性質が便利なこともあります。時間のかかる計算を行う関数があるときに
使われる一般的な技法は、関数が呼び出されるごとにパラメタと結果の値をキ
ャッシュし、再び同じ値が要求されたらキャッシュされた値を返すというもの
です。これは "memoizing" と呼ばれ、このように実装されます:

   # Callers will never provide a third parameter for this function.
   def expensive(arg1, arg2, _cache={}):
       if (arg1, arg2) in _cache:
           return _cache[(arg1, arg2)]

       # Calculate the value
       result = ... expensive computation ...
       _cache[(arg1, arg2)] = result           # Store result in the cache
       return result

デフォルト値の代わりに、辞書を含むグローバル変数も使えます。これは好み
の問題です。


オプションパラメータやキーワードパラメータを関数から関数へ渡すにはどうしたらいいですか？
----------------------------------------------------------------------------------------

関数のパラメータリストに引数を "*" と "**" 指定子 (specifier) で集めて
ください。そうすれば、固定引数をタプルとして、キーワード引数を辞書とし
て得られます。これで、他の関数を呼び出すときに "*" と "**" を使ってそ
れらの引数を渡せます:

   def f(x, *args, **kwargs):
       ...
       kwargs['width'] = '14.3c'
       ...
       g(x, *args, **kwargs)

あまりありませんが、Python の 2.0 以前のバージョンを考慮するときは、代
わりに "apply()" を使ってください:

   def f(x, *args, **kwargs):
       ...
       kwargs['width'] = '14.3c'
       ...
       apply(g, (x,)+args, kwargs)


実引数と仮引数の違いは何ですか?
-------------------------------

*仮引数 (parameter)* は関数定義に表れる名前で定義されるのに対し、 *実
引数 (argument)* は関数を呼び出すときに実際に渡す値のことです。仮引数
は関数が受け取ることの出来る実引数の型を定義します。例えば、以下のよう
な関数定義があったとして:

   def func(foo, bar=None, **kwargs):
       pass

*foo*、*bar*、*kwargs* は "func" の仮引数です。一方、"func" を呼び出す
ときには、例えば:

   func(42, bar=314, extra=somevar)

"42"、"314"、"somevar" という値は実引数です。


なぜ list 'y' を変更すると list 'x' も変更されるのですか?
---------------------------------------------------------

次のようなコードを書いたとします:

   >>> x = []
   >>> y = x
   >>> y.append(10)
   >>> y
   [10]
   >>> x
   [10]

どうして "y" への要素の追加が "x" も変更してしまうのか疑問に思うかもし
れません。

このような結果になる2つの要因があります:

1. 変数とは、単にオブジェクトを参照するための名前に過ぎません。 "y
   = x" とすることは、リストのコピーを作りません -- それは "x" が参照
   す るのと同じオブジェクトを参照する新しい変数 "y" を作ります。つま
   り、 あるのは一つのオブジェクト(この場合リスト)だけであって、 "x"
   と "y" の両方がそれを参照しているのです。

2. リストは *mutable* です。内容を変更出来る、ということです。

"append()" 呼び出しの後、ミュータブルオブジェクトの内容が "[]" から
"[10]" に変わります。 変数が同じオブジェクトを参照しているので、どちら
の名前であっても変更された値 "[10]" にアクセスします。

代わりに "x" にイミュータブルを代入すると:

   >>> x = 5  # ints are immutable
   >>> y = x
   >>> x = x + 1  # 5 can't be mutated, we are creating a new object here
   >>> x
   6
   >>> y
   5

この場合ご覧の通り "x" と "y" はまったく同じではありませんね。これは整
数が *immutable* だからで、 "x = x + 1" は整数の "5" の値を変更してい
るのではありません; 代わりに新しいオブジェクト(整数 "6")を作って "x"
に代入しています (つまり "x" が参照するオブジェクトが変わります)。この
代入の後では私たちは 2 つのオブジェクト(整数の "6" と "5")を持っていて
、2 つの変数はそれらを参照しています("x" はいまや "6" を参照しています
が "y" は "5" を参照したままです)。

ある演算 (たとえば "y.append(10)", "y.sort()") がオブジェクトを変更す
る一方で、外見上は似た演算 (たとえば "y = y + [10]", "sorted(y)") は新
しいオブジェクトを作ります。Python では一般に (そして標準ライブラリの
全てのケースで)、このような 2 つのタイプの演算にまつわる混乱を避けるた
めに、オブジェクトを変更するメソッドは "None" を返します。ですからもし
あなたが誤って "y" の複製の並び替えをするつもりで "y.sort()" と書いた
場合に結果手にするのは "None" でしょうから、あなたのプログラムは簡単に
診断出来るエラーを起こすでしょう。

しかしながら、同じ操作が型ごとに異なる振る舞いをする演算の種類が一つあ
ります: 累算代入演算です。例えば "+=" はリストを変更しますが、タプルや
整数は変更しません("a_list += [1, 2, 3]" は "a_list.extend([1, 2, 3])"
と同じ意味で、そして "a_list" を変更しますが、 "some_tuple += (1, 2,
3)" と "some_int += 1" は新しいオブジェクトを作ります)。

言い換えると:

* ミュータブルなオブジェクト("list", "dict", "set", 等)を持っている
  場 合、私たちはその内容を変更するある種の演算を使うことが出来、それ
  を参 照している全ての変数はその変化を見ることになるでしょう。

* イミュータブルなオブジェクト("str", "int", "tuple", 等)を持ってい
  る 場合、それを参照している全ての変数は同じ値を参照しているでしょう
  が、 持っている値を新しい値に変換する演算はいつでも新しいオブジェク
  トを返 します。

2つの変数が同じオブジェクトを参照しているかどうかが知りたければ、 "is"
オペレータまたは組み込み関数 "id()" が使えます。


パラメータを出力する関数 (参照渡し) はどのように書きますか？
------------------------------------------------------------

前提として、Python では引数は代入によって渡されます。代入はオブジェク
トへの参照を作るだけなので、呼び出し元と呼び出し先にある引数名の間にエ
イリアスはありませんし、参照渡しそれ自体はありません。望む効果を得るた
めには幾つかの方法があります。

1. 結果のタプルを返すことによって:

      def func2(a, b):
          a = 'new-value'        # a and b are local names
          b = b + 1              # assigned to new objects
          return a, b            # return new values

      x, y = 'old-value', 99
      x, y = func2(x, y)
      print x, y                 # output: new-value 100

   これはたいてい一番明確な方法です。

2. グローバル変数を使って。これはスレッドセーフでないので、推奨され
   ま せん。

3. ミュータブルな (インプレースに変更可能な) オブジェクトを渡すこと
   に よって:

      def func1(a):
          a[0] = 'new-value'     # 'a' references a mutable list
          a[1] = a[1] + 1        # changes a shared object

      args = ['old-value', 99]
      func1(args)
      print args[0], args[1]     # output: new-value 100

4. 変更される辞書に渡すことによって:

      def func3(args):
          args['a'] = 'new-value'     # args is a mutable dictionary
          args['b'] = args['b'] + 1   # change it in-place

      args = {'a': 'old-value', 'b': 99}
      func3(args)
      print args['a'], args['b']

5. または、クラスインスタンスに値を同梱することによって:

      class callByRef:
          def __init__(self, **args):
              for (key, value) in args.items():
                  setattr(self, key, value)

      def func4(args):
          args.a = 'new-value'        # args is a mutable callByRef
          args.b = args.b + 1         # change object in-place

      args = callByRef(a='old-value', b=99)
      func4(args)
      print args.a, args.b

   このような複雑なことをする理由はめったに無いでしょう。

一番の選択は、複数の結果を含むタプルを返すことです。


Python で高次関数はどのようにつくりますか？
-------------------------------------------

二つの方法があります: ネストされたスコープを使う方法と、呼び出し可能オ
ブジェクトを使う方法です。例えば、"a*x+b" の値を計算する "f(x)" 関数を
返す "linear(a,b)" を定義したいとします。ネストされたスコープを使うと:

   def linear(a, b):
       def result(x):
           return a * x + b
       return result

また、呼び出し可能オブジェクトを使うと:

   class linear:

       def __init__(self, a, b):
           self.a, self.b = a, b

       def __call__(self, x):
           return self.a * x + self.b

どちらの場合でも、

   taxes = linear(0.3, 2)

とすれば、"taxes(10e6) == 0.3 * 10e6 + 2" となるような呼び出し可能オブ
ジェクトを得られます。

呼び出し可能オブジェクトを使う方法は、少し遅くなり、わずかにコードが長
くなるという短所があります。ですが、継承を使ってコーラブル同士で記号を
共有することもできます:

   class exponential(linear):
       # __init__ inherited
       def __call__(self, x):
           return self.a * (x ** self.b)

オブジェクトはいくつかのメソッドに状態をカプセル化できます:

   class counter:

       value = 0

       def set(self, x):
           self.value = x

       def up(self):
           self.value = self.value + 1

       def down(self):
           self.value = self.value - 1

   count = counter()
   inc, dec, reset = count.up, count.down, count.set

ここで、"inc()"、"dec()"、"reset()" は同じカウント変数を共有する関数の
ようにふるまいます。


Python のオブジェクトはどのようにコピーしますか？
-------------------------------------------------

一般的に、普通は "copy.copy()" や "copy.deepcopy()" を試してください。
何でもコピーできるとは限りませんが、たいていはできます。

もっと簡単にコピーできるオブジェクトもあります。辞書には "copy()" メソ
ッドがあります:

   newdict = olddict.copy()

シーケンスはスライシングでコピーできます:

   new_l = l[:]


オブジェクトのメソッドや属性はどのように見つけますか？
------------------------------------------------------

ユーザー定義クラスのインスタンス x で、"dir(x)" はインスタンス属性とそ
のクラスで定義されたメソッドや属性を含む名前のアルファベット順リストを
返します。


コードはどのようにオブジェクトの名前を見つけるのですか？
--------------------------------------------------------

概して、オブジェクトは本当は名前を持たないので、見つけることはできませ
ん。本質的には、代入とはいつも値に名前を束縛することです。"def" と
"class" 文も同じですが、この場合は値はコーラブルです。以下のコードを考
えてみましょう:

   >>> class A:
   ...     pass
   ...
   >>> B = A
   >>> a = B()
   >>> b = a
   >>> print b
   <__main__.A instance at 0x16D07CC>
   >>> print a
   <__main__.A instance at 0x16D07CC>

おそらく、このクラスには名前があります。このクラスは二つの名前に縛られ
て、名前 B を通して呼び出されますが、それでもクラス A のインスタンスと
して報告されるのです。しかし、両方の名前が同じ値に束縛されている以上、
このインスタンスの名前が a か b か決めることはできないのです。

概して、コードにとってある値の「名前を知っている」事は重要ではありませ
ん。あなたがわざと内省的なコードを書いているのでない限り、方針を変えた
方がいいかもしれないということになるでしょう。

comp.lang.python で、Fredrik Lundh はこの問題の答えとして素晴らしい喩
えをしてくれました:

   玄関にいた猫の名前を知るのと同じ方法です: その猫 (オブジェクト) 自
   体はその名前を言うことができないし、それは実は問題ではありません --
   その猫が何と呼ばれているかを知る唯一の方法は、すべての隣人 (名前空
   間) にその猫 (オブジェクト) が何と呼ばれているかを聞くことです。

   ……そして、その猫が沢山の名前で知られていたり、逆に全く名前が無かっ
   たりしても驚かないでください！


カンマ演算子はなぜ優先されるのですか？
--------------------------------------

カンマは Python では演算子ではありません。このセッションを考えてくださ
い:

   >>> "a" in "b", "a"
   (False, 'a')

カンマは演算子ではなく、式の分離子なので、上の式は次の式と同じように評
価されます:

   ("a" in "b"), "a"

こうではありません:

   "a" in ("b", "a")

他のさまざまな演算子("="、"+=" など)も同じです。これらは真の演算子では
ありませんが、代入文の構文上のデリミタです。


C の "?:" 三項演算子と等価なものはありますか？
----------------------------------------------

はい、この機能は Python 2.5 で追加されました。構文は以下のようになりま
す:

   [on_true] if [expression] else [on_false]

   x, y = 50, 25

   small = x if x < y else y

2.5 以前のバージョンについては、これの答えは「いいえ」です。


Python で解し難いワンライナーを書くことはできますか？
-----------------------------------------------------

はい。そういうものはたいてい、 "lambda" の中に "lambda" がネストされて
います。Ulf Bartelt による下の３つの例を見てください:

   # Primes < 1000
   print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
   map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))

   # First 10 Fibonacci numbers
   print map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1: f(x,f),
   range(10))

   # Mandelbrot set
   print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
   Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
   Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
   i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
   >=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
   64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
   ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
   #    \___ ___/  \___ ___/  |   |   |__ lines on screen
   #        V          V      |   |______ columns on screen
   #        |          |      |__________ maximum of "iterations"
   #        |          |_________________ range on y axis
   #        |____________________________ range on x axis

よい子はまねしないでね！


数と文字列
==========


十六進数や八進数を指定するにはどうしたらいいですか？
----------------------------------------------------

八進数を指定するには、八進数での値の先頭に 0 と "o" (小文字または大文
字) を加えてください。たとえば、変数 "a" に八進数での "10" (十進数での
"8") を代入するには、こう打ってください:

   >>> a = 0o10
   >>> a
   8

十六進数も簡単です。ただ十六進数での値の先頭に 0 と "x" (小文字または
大文字) を加えてください。十六進数は小文字でも大文字でも指定できます。
たとえば、Python インタプリタで:

   >>> a = 0xa5
   >>> a
   165
   >>> b = 0XB2
   >>> b
   178


なぜ -22 // 10 は -3 を返すのですか？
-------------------------------------

"i % j" が "j" と同じ符号であってほしいことに基づいています。それに加
えて以下のようにもしたいとすると:

   i == (i // j) * j + (i % j)

整数除算は床を返すことになります。C にも C の一貫性があって、"i % j"
が "i" と同じ符号を持つように "i // j" を丸めています。

"i % j" は、"j" が負の時には実際にはほとんど使いません。"j" が正なら、
たくさん使います。その事実上すべての場合、"i % j" は ">= 0" となる方が
便利です。時計が 10 時を指している時、その 200 時間前は何時でしょうか
。"-190 % 12 == 2" となるのが便利です。"-190 % 12 == -10" は噛み付きか
ねないバグです。

注釈: Python 2 では、  "__future__.division" が有効でなければ、"a /
  b" は "a // b" と同じ結果を返します。これは "古典的な (classic)" 除
  算とも 呼ばれます。


文字列を数に変換するにはどうしたらいいですか？
----------------------------------------------

整数に変換するには、組み込みの "int()" 型コンストラクタを使ってくださ
い。例えば、 "int('144') == 144" です。同様に、 "float()" は浮動小数点
に変換します。例えば、 "float('144') == 144.0" です。

デフォルトでは、これらは数を十進数として解釈するので、 "int('0o144')"
や "int('0x144')" は "ValueError" を送出します。 "int(string, base)"
はオプションの第二引数をとって変換元の基数にします。つまり
"int('0x144', 16) == 324" です。基数が 0 と指定された場合、その数は
Python の基準によって解釈されます。先頭が '0o' なら八進数で、'0x' なら
十六進数を表します。

文字列を数に変換するだけのために "eval()" を使わないでください。
"eval()" は特に遅いですし、セキュリティ上のリスクもあります。求められ
ない副作用を持つような Python の式を渡そうとする人がいるかも知れません
。例えば、あなたのホームディレクトリを消去する
"__import__('os').system("rm -rf $HOME")" を渡そうとする人がいるかも知
れません。

"eval()" にも数を Python の式として解釈する機能があります。だから例え
ば、 "eval('09')" は構文エラー起こします。Python は '0' で始まる数を八
進数 (基数 8) とみなすからです。


数を文字列に変換するにはどうしたらいいですか？
----------------------------------------------

To convert, e.g., the number 144 to the string '144', use the built-in
type constructor "str()".  If you want a hexadecimal or octal
representation, use the built-in functions "hex()" or "oct()".  For
fancy formatting, see the 書式指定文字列の文法 section, e.g.
""{:04d}".format(144)" yields "'0144'" and ""{:.3f}".format(1.0/3.0)"
yields "'0.333'". In Python 2, the division (/) operator returns the
floor of the mathematical result of division if the arguments are ints
or longs, but it returns a reasonable approximation of the division
result if the arguments are floats or complex:

   >>> print('{:.3f}'.format(1/3))
   0.000
   >>> print('{:.3f}'.format(1.0/3))
   0.333

In Python 3, the default behaviour of the division operator (see **PEP
238**) has been changed but you can have the same behaviour in Python
2 if you import "division" from "__future__":

   >>> from __future__ import division
   >>> print('{:.3f}'.format(1/3))
   0.333

You may also use the % operator on strings.  See the library reference
manual for details.


文字列をインプレースに変更するにはどうしたらいいですか？
--------------------------------------------------------

文字列はイミュータブルなので、変更することはできません。それができるオ
ブジェクトを作るには、その文字列をリストに変換してみるか、array モジュ
ールを使ってください:

   >>> import io
   >>> s = "Hello, world"
   >>> a = list(s)
   >>> print a
   ['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
   >>> a[7:] = list("there!")
   >>> ''.join(a)
   'Hello, there!'

   >>> import array
   >>> a = array.array('c', s)
   >>> print a
   array('c', 'Hello, world')
   >>> a[0] = 'y'; print a
   array('c', 'yello, world')
   >>> a.tostring()
   'yello, world'


関数やメソッドを呼ぶのに文字列を使うにはどうしたらいいですか？
--------------------------------------------------------------

様々なテクニックがあります。

* 一番いいのは、文字列を関数に対応させる辞書を使うことです。このテク
  ニ ックの一番の利点は、文字列が関数の名前と同じ必要がないことです。
  この 方法は case 構造をエミュレートするための一番のテクニックでもあ
  ります :

     def a():
         pass

     def b():
         pass

     dispatch = {'go': a, 'stop': b}  # Note lack of parens for funcs

     dispatch[get_input()]()  # Note trailing parens to call function

* 組み込み関数の "getattr()" を使う方法:

     import foo
     getattr(foo, 'bar')()

  なお、 "getattr()" はクラス、クラスインスタンス、モジュールなど、ど
  んなオブジェクトにも使えます。

  これは標準ライブラリでも何箇所か使われています。このように:

     class Foo:
         def do_foo(self):
             ...

         def do_bar(self):
             ...

     f = getattr(foo_instance, 'do_' + opname)
     f()

* "locals()" や "eval()" を使って関数名を決める方法:

     def myFunc():
         print "hello"

     fname = "myFunc"

     f = locals()[fname]
     f()

     f = eval(fname)
     f()

  ノート: "eval()" の使用は遅いし危険です。もしあなたが文字列の内容を
  絶対的に支配できなければ、任意の関数を実行されるようにする文字列を渡
  す人がいるかも知れません。


文字列から後端の改行を取り除く Perl の chomp() に相当するものはありますか？
---------------------------------------------------------------------------

Python 2.2 からは、 "S.rstrip("\r\n")" を使って文字列 "S" の終端から他
の空白文字を取り除くことなくすべての行末記号を取り除くことができます。
文字列 "S" が複数行を表し、終端に空行があるとき、そのすべての空行も取
り除かれます:

   >>> lines = ("line 1 \r\n"
   ...          "\r\n"
   ...          "\r\n")
   >>> lines.rstrip("\n\r")
   'line 1 '

これは典型的に一度に一行ずつテキストを読みたい時にのみ使われるので、
"S.rstrip()" をこの方法で使うとうまくいきます。

古いバージョンの Python では、部分的な代用品が二つあります:

* すべての終端の空白文字を取り除きたいなら、文字列オブジェクトの
  "rstrip()" メソッドを使ってください。これは改行記号一つだけでなく、
  すべての終端の空白文字を取り除きます。

* そうでなく、文字列 "S" に一行しか無いなら、"S.splitlines()[0]" を
  使 ってください。


scanf() や sscanf() と同等なものはありますか？
----------------------------------------------

そのようなものはありません。

簡単な入力解析で、多くの場合に一番簡単な方法は、文字列オブジェクトの
"split()" メソッドで行を空白文字で区切られた単語に分け、十進数の文字列
を "int()" や "float()" で数値に変換することです。 "split()" にはオプ
ションの "sep" 変数があり、行に空白文字以外の区切りを使っているときに
便利です。

もっと複雑な入力解析をしたいなら、C の "sscanf()" よりも正規表現の方が
便利ですし、この処理に向いています。


'UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)' とはどういう意味ですか？
---------------------------------------------------------------------------------------------------

このエラーは、あなたの Python インストールが 7-bit ASCII 文字列しか扱
えないことを表します。この問題を扱うには二つの方法があります。

あなたのプログラムが、任意の文字セットエンコーディングのデータを扱わな
ければならないなら、一般に、アプリケーションが起動する環境によってデー
タのエンコーディングが特定されます。入力をそのエンコーディングを使って
Unicode に変換する必要があります。例えば、email や web 入力を扱うプロ
グラムは、概して文字セットエンコーディング情報を Content-Type ヘッダか
ら見つけます。これに使うことで、入力データを Unicode に正しく変換でき
ます。 "value" によって参照される文字列が UTF-8 でエンコードされている
とすれば:

   value = unicode(value, "utf-8")

は Unicode オブジェクトを返します。データが UTF-8 に正しく変換されない
なら、上記の呼び出しは "UnicodeError" 例外を送出します。

非 ASCII データを持つ文字列を Unicode に変換すればいいだけなら、まず
ASCII エンコーディングを仮定して変換し、失敗したら Unicode オブジェク
トを生成すればいいです:

   try:
       x = unicode(value, "ascii")
   except UnicodeError:
       value = unicode(value, "utf-8")
   else:
       # value was valid ASCII data
       pass

デフォルトのエンコーディングは、Python ライブラリの一部である
"sitecustomize.py" と呼ばれるファイルで設定できます。しかし、Python 全
体におけるデフォルトのエンコーディングを変えてしまうことは、サードパー
ティ拡張モジュールの失敗につながるのでお勧めできません。

なお、Windows には、 "mbcs" として知られるエンコーディングがあり、これ
はあなたのロケールに依存するエンコーディイングを使います。多くの場合、
特に COM で作業をするとき、これが使うのに適したデフォルトのエンコーデ
ィングです。


シーケンス(タプル/リスト)
=========================


タプル、リスト間の変更はどのようにするのですか？
------------------------------------------------

型コンストラクタ "tuple(seq)" はすべてのシーケンス (実際には、すべての
イテラブル) を同じ要素、同じ順序のタプルに変換します。

例えば、 "tuple([1, 2, 3])" は "(1, 2, 3)" を与え、 "tuple('abc')" は
"('a', 'b', 'c')" を与えます。引数がタプルなら、コピーを作らずに引数の
オブジェクトそのものを返すので、あるオブジェクトが既にタプルになってい
るか確信が持てないのなら、 "tuple()" を呼ぶのが手軽です。

型コンストラクタ "list(seq)" はすべてのシーケンスあるいはイテラブルを
同じ要素、同じ順序のリストに変換します。例えば、"list((1, 2, 3))" は
"[1, 2, 3]" を与え、"list('abc')" は "['a', 'b', 'c']" を与えます。引
数がリストなら、"seq[:]" と同様にコピーを作ります。


インデクスが負の場合はどうなりますか？
--------------------------------------

Python のシーケンスは正の数と負の数でインデクスされます。正の数では、0
が最初のインデクス、1 が 2 番目のインデクス、以下も同様です。負のイン
デクスでは、-1 が最後のインデクス、-2 が最後から 2 番目のインデクス、
以下も同様です。"seq[-n]" は "seq[len(seq)-n]" と同じだと考えてくださ
い。

負のインデクスを使うと便利なことがあります。例えば、"S[:-1]" は文字列
の最後以外のすべての文字を表すので、文字列の末尾の改行を取り除くときに
便利です。


シーケンスを逆順にイテレートするにはどうしたらいいですか？
----------------------------------------------------------

Python 2.4 で追加された "reversed()" を使ってください:

   for x in reversed(sequence):
       ...  # do something with x ...

これは元のシーケンスをいじるのではなく、逆順の新しいコピーを作ってイテ
レートさせます。

Python 2.3 では、拡張スライス構文を使います:

   for x in sequence[::-1]:
       ...  # do something with x ...


リストから重複を取り除くにはどうしますか？
------------------------------------------

Python Cookbook の長い議論に多くの方法があるので参照してください:

   https://code.activestate.com/recipes/52560/

リストを並び替えて構わないのなら、ソートした上でリストの最初から最後ま
でを調べ、次のように重複を削除してください:

   if mylist:
       mylist.sort()
       last = mylist[-1]
       for i in range(len(mylist)-2, -1, -1):
           if last == mylist[i]:
               del mylist[i]
           else:
               last = mylist[i]

リストのすべての要素が辞書のキーとして使える (つまり、すべての要素が
hashable) なら、おそらくこのほうが速いです:

   d = {}
   for x in mylist:
       d[x] = 1
   mylist = list(d.keys())

Python 2.5 以上では、以下を代わりに使えます:

   mylist = list(set(mylist))

リストを集合に変換するときに重複は取り除かれるので、それをリストに戻せ
ばいいのです。


Python で配列を作るにはどうしますか？
-------------------------------------

リストを使ってください:

   ["this", 1, "is", "an", "array"]

リストの時間計算量は C や Pascal の配列と同じです。大きな違いは、
Python のリストは多くの異なる型のオブジェクトを含めることです。

"array" モジュールにも固定された型を簡潔に表現する配列を作るためのメソ
ッドがありますが、リストよりもインデクスが遅いです。また、Numeric 拡張
その他でも、様々な特徴をもつ配列的な構造体が定義されています。

Lisp 方式の連結リストを得るのに、タプルを使ってコンスセルをエミュレー
トできます:

   lisp_list = ("like",  ("this",  ("example", None) ) )

ミュータブルな必要があるなら、タプルではなくリストを使いましょう。lisp
の car にあたるものが "lisp_list[0]" で、cdr にあたるものが
"lisp_list[1]" です。本当に必要だと確信できるとき以外はこれはしないで
ください。たいてい、これは Python のリストを使うよりも非常に遅いですか
ら。


多次元のリストを作るにはどうしますか？
--------------------------------------

このようにして多次元の配列を作ろうとしてしまったことがあるでしょう:

   >>> A = [[None] * 2] * 3

これを表示したときには問題なさそうに見えます:

   >>> A
   [[None, None], [None, None], [None, None]]

しかし値を代入すると、その値が複数の場所に現れてしまいます:

>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]

これは、"*" を使ったリストの複製がコピーを作らず、存在するオブジェクト
への参照を作るだけだからです。この "*3" は長さ 2 の同じリストへの参照
を含むリストを作ります。一つの列に対する変更はすべての列に現れますが、
これが望んだ結果であることはまずないでしょう。

おすすめの方法は、最初に望んだ長さのリストを作り、それから新しく作った
リストでそれぞれの要素を埋めていくことです:

   A = [None] * 3
   for i in range(3):
       A[i] = [None] * 2

これは長さ 2 の異なるリスト 3 つを含むリストを生成します。リスト内包表
記も使えます:

   w, h = 2, 3
   A = [[None] * w for i in range(h)]

あるいは、行列データ型を提供している拡張を使用することもできます;
NumPy が最もよく知られています。


オブジェクトのシーケンスにメソッドを適用するにはどうしますか？
--------------------------------------------------------------

リスト内包表記を使ってください:

   result = [obj.method() for obj in mylist]

もっと一般化したければ、以下の関数を試してみてください:

   def method_map(objects, method, arguments):
       """method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]"""
       nobjects = len(objects)
       methods = map(getattr, objects, [method]*nobjects)
       return map(apply, methods, [arguments]*nobjects)


なぜ加算はされるのに a_tuple[i] += ['item'] は例外を送出するのですか?
---------------------------------------------------------------------

これは、拡張代入演算子は *代入* 演算子だ、という事実と、Python での可
変オブジェクトと不変オブジェクトの違いが組み合わさって起きるのです。

この議論は一般的に、可変オブジェクトを指すタプルの要素に、拡張代入演算
子が適用されたときにも適用できますが、例として "list" と "+=" を使いま
す。

次のように書いたとします:

   >>> a_tuple = (1, 2)
   >>> a_tuple[0] += 1
   Traceback (most recent call last):
      ...
   TypeError: 'tuple' object does not support item assignment

例外が送出された理由は明らかです: "1" が ("1") を指すオブジェクト
"a_tuple[0]" に加えられ、結果のオブジェクト "2" が生成されますが、計算
結果 "2" をタプルの第 "0" 要素に代入しようとしたときに、エラーが発生し
ます。なぜならば、タプルの要素が何を指すかは変えられないからです。

このような裏事情の元、拡張代入文はだいたい次のようなことをしています:

   >>> result = a_tuple[0] + 1
   >>> a_tuple[0] = result
   Traceback (most recent call last):
     ...
   TypeError: 'tuple' object does not support item assignment

タプルは不変なので、例外を生み出しているのは操作の代入部分なのです。

次のように書いたとします:

   >>> a_tuple = (['foo'], 'bar')
   >>> a_tuple[0] += ['item']
   Traceback (most recent call last):
     ...
   TypeError: 'tuple' object does not support item assignment

この例外にはちょっと驚きますが、もっと驚くべきことは、エラーがあったと
しても追記はきちんと動いている、という事実です:

   >>> a_tuple[0]
   ['foo', 'item']

なぜこれが起きるかを調べるためには、次の 2 点を知っている必要がありま
す。(a) オブジェクトに "__iadd__" 特殊メソッドが実装されている場合、拡
張代入 "+=" が実行されるときにそれが呼び出され、その返り値が代入文で使
われます; (b) リストでは、"__iadd__" は "extend" の呼び出しと等価で、
リストを返します。こんな理由で、リストでは "+=" は "list.extend" の "
略記" だと言ったのでした:

   >>> a_list = []
   >>> a_list += [1]
   >>> a_list
   [1]

これは次のと等価です:

   >>> result = a_list.__iadd__([1])
   >>> a_list = result

a_list が指していたオブジェクトは更新され、更新されたオブジェクトへの
ポインタは再度 "a_list" に代入されます。代入しているのは、"a_list" が
更新前まで指していた同じオブジェクトへのポインタなので、代入は最終的に
は何もしていないのですが、代入処理自体は起きています。

従って、今のタプルの例では、次のと同じことが起きています:

   >>> result = a_tuple[0].__iadd__(['item'])
   >>> a_tuple[0] = result
   Traceback (most recent call last):
     ...
   TypeError: 'tuple' object does not support item assignment

"__iadd__" は成功し、リストは拡張 (extend) されますが、"result" が
"a_tuple[0]" が既に指しているオブジェクトと同じオブジェクトを指してい
たとしても、タプルは不変なので、その最後の代入はやはりエラーとなります
。


辞書
====


一貫した順序でキーを表示する辞書はありますか?
---------------------------------------------

できません。辞書はキーを予測できない順序で保存しているので、辞書の要素
が表示される順序もまた予測できないのです。

ファイルに印字可能なバージョンを保存し、変更を加えてから他の印字された
辞書と比較したい時に苛立たしいかもしれません。この場合は、 "pprint" モ
ジュールで辞書を整形して表示してください。要素がキーでソートされて表さ
れます。

もっと複雑な解決策は、 "dict" のサブクラスとして "SortedDict" クラスを
作り、それに予測可能な順序で自身を表示させることです。そのようなクラス
の単純な実装の一つは:

   class SortedDict(dict):
       def __repr__(self):
           keys = sorted(self.keys())
           result = ("{!r}: {!r}".format(k, self[k]) for k in keys)
           return "{{{}}}".format(", ".join(result))

       __str__ = __repr__

これは完璧な解法とは程遠いですが、多くの状況でうまく働くでしょう。最大
の欠点は、辞書内のどれかの値がまた辞書であった場合に、それらの値はどん
な特定の順序でも表示されないことです。


複雑なソートがしたいのですが、Python でシュワルツ変換はできますか？
-------------------------------------------------------------------

Perl コミュニティの Randal Schwartz の作とされるこのテクニックは、それ
ぞれの要素に「ソート値」を対応付けるある尺度によって、リストの要素をソ
ートします。 Python では、 "sort()" 関数で "key" 引数を使ってください:

   Isorted = L[:]
   Isorted.sort(key=lambda s: int(s[10:15]))


リストを別のリストの値によってソートするにはどうしますか？
----------------------------------------------------------

二つのリストを混ぜあわせてタプルのリストにしてから、必要な要素を選んで
ください:

   >>> list1 = ["what", "I'm", "sorting", "by"]
   >>> list2 = ["something", "else", "to", "sort"]
   >>> pairs = zip(list1, list2)
   >>> pairs
   [('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')]
   >>> pairs.sort()
   >>> result = [ x[1] for x in pairs ]
   >>> result
   ['else', 'sort', 'to', 'something']

最後の段階の別のやり方は:

   >>> result = []
   >>> for p in pairs: result.append(p[1])

これのほうが読みやすいと、最後のリスト内包表記ではなくこれを使いたくな
るかもしれません。しかし、これは長いリストではほぼ二倍の時間がかかりま
す。なぜでしょうか。まず、"append()" 演算はメモリを割り当て直す必要が
あり、それを避けるために毎回ちょっと工夫していますが、それでも避けられ
ないことがあるので、少し時間がかかるのです。二つ目に、"result.append"
には属性探索が余計に必要で、三つ目に、これらすべての関数を呼ぶ必要があ
ることで速度が落ちてしまいます。


オブジェクト
============


クラスとは何ですか？
--------------------

クラスは、class 文の実行で生成される特殊なオブジェクトです。クラスオブ
ジェクトはインスタンスオブジェクトを生成するためのテンプレートとして使
われ、あるデータ型に特有のデータ (attribute/属性) とコード (メソッド)
の両方を内蔵しています。

新しいクラスを一つ以上の他のクラス (新しいクラスの基底クラスと呼ばれま
す) に基づいて作ることもできます。この新しいクラスは、基底クラスから属
性とメソッドを継承します。これにより、オブジェクトモデルを継承で連続的
に洗練できます。メールボックスへの基本的なアクセサを提供する一般的な
"Mailbox" クラスを作って、それからいろいろな特定のメールボックスの形式
を扱う "MboxMailbox"、"MaildirMailbox"、"OutlookMailbox" のようなサブ
クラスを作れるのです。


メソッドとは何ですか？
----------------------

メソッドは、オブジェクト "x" が持つ関数で、通常 "x.name(arguments...)"
として呼び出されるものです。メソッドはクラス定義の中で関数として定義さ
れます:

   class C:
       def meth(self, arg):
           return arg * 2 + self.attribute


self とは何ですか？
-------------------

self はメソッドの第一引数に慣習的につけられる名前にすぎません。
"meth(self, a, b, c)" として定義されたメソッドは、その定義がなされたク
ラスのインスタンス "x" に対して "x.meth(a, b, c)" として呼び出されます
。呼び出されたメソッドは、"meth(x, a, b, c)" が呼ばれたものと考えます
。

なぜメソッドの定義や呼び出しにおいて 'self' を明示しなければならないの
ですか？ も参照してください。


あるオブジェクトが、与えられたクラスやそのサブクラスのインスタンスであるかを調べるにはどうしますか？
----------------------------------------------------------------------------------------------------

ビルトイン関数 "isinstance(obj, cls)" を使ってください。クラスのタプル
を与えて "isinstance(obj, (class1, class2, ...))" のようにすれば、ある
オブジェクトが任意の数のクラスのオブジェクトであるかを調べられますし、
"isinstance(obj, str)" や "isinstance(obj, (int, long, float,
complex))" のようにすれば、Python のビルトイン型のオブジェクトであるか
も調べられます。

なお、大部分のプログラムでは、 "isinstance()" をユーザー定義のクラスに
何度も使うべきではありません。クラスを自分で開発するときに、適切なオブ
ジェクト指向スタイルは、特定の振る舞いをカプセル化するクラスのメソッド
を定義するものであって、オブジェクトのクラスを調べてそのクラスに応じて
違うことをするものではありません。例えば、何かをする関数があったとして
:

   def search(obj):
       if isinstance(obj, Mailbox):
           ...  # code to search a mailbox
       elif isinstance(obj, Document):
           ...  # code to search a document
       elif ...

よりよいアプローチは、"search()" メソッドをすべてのクラスに定義して、
それをただ呼び出すことです:

   class Mailbox:
       def search(self):
           ...  # code to search a mailbox

   class Document:
       def search(self):
           ...  # code to search a document

   obj.search()


委譲とは何ですか？
------------------

委譲 (delegation) とは、オブジェクト指向のテクニック (デザインパターン
とも呼ばれる) の一つです。オブジェクト "x" があって、そのメソッドのう
ちただ一つの振る舞いを変えたいとしましょう。新しいクラスを作成し、変え
たいメソッドだけを新しく実装し、他のすべてのメソッドを "x" の対応する
メソッドに委譲する新しいクラスを作れます。

Python プログラマは簡単に委譲を実装できます。例えば、以下のクラスは、
ファイルのように振る舞いながらすべての文字を大文字に変換するクラスを実
装します:

   class UpperOut:

       def __init__(self, outfile):
           self._outfile = outfile

       def write(self, s):
           self._outfile.write(s.upper())

       def __getattr__(self, name):
           return getattr(self._outfile, name)

ここで "UpperOut" クラスは "write()" メソッドを定義しなおして、引数の
文字列を大文字に変換してから基礎となる "self.__outfile.write()" メソッ
ドを呼び出すようにします。その他すべてのメソッドは基礎となる
"self.__outfile" オブジェクトに移譲されます。この委譲は "__getattr__"
メソッドを通してなされます。属性の制御の詳細は 言語リファレンス を参照
してください。

なお、一般的に委譲はトリッキーになりがちです。属性が設定される時には読
み出される時と同様に、そのクラスに "__setattr__()" メソッドを定義する
必要があり、それには細心の注意が必要です。 "__setattr__()" の基本的な
実装はおおよそ以下のようになります:

   class X:
       ...
       def __setattr__(self, name, value):
           self.__dict__[name] = value
       ...

たいてい、 "__setattr__()" 実装は "self.__dict__" を変更して、無限再帰
を起こすことなくローカルな状態を保存するようにしなければなりません。


基底クラスで定義されたメソッドを、そのクラスをオーバーライドした派生クラスから呼び出すにはどうしますか？
--------------------------------------------------------------------------------------------------------

新スタイルのクラスを使っている場合は、組み込みの "super()" 関数を使っ
てください:

   class Derived(Base):
       def meth(self):
           super(Derived, self).meth()

旧スタイルクラスを使っているなら: "class Derived(Base): ..." のような
クラス定義で、 "Base.meth(self, arguments...)" とすれば、 "Base" (また
は "Base" の基底クラス) で定義された "meth()" メソッドを呼び出せます。
ここで、 "Base.meth" は束縛されていないメソッドなので、 "self" 引数を
渡す必要があります。


基底クラスの名前を変えやすいコードを書くにはどうしますか？
----------------------------------------------------------

基底クラスのエイリアス (alias) を定義し、先にそれに本当の基底クラスを
代入しておいてから、クラス定義の中でそのエイリアスを使うといいかもしれ
ません。そうすればエイリアスに代入する値を変えるだけで済みます。ちなみ
に、この手法は使用する基底クラスを動的に選びたいとき、例えば使えるリソ
ースによって選びたいときなどにも便利です。例:

   BaseAlias = <real base class>

   class Derived(BaseAlias):
       def meth(self):
           BaseAlias.meth(self)
           ...


静的なクラスデータや静的なクラスメソッドを作るにはどうしますか？
----------------------------------------------------------------

(C++ や Java の意味で) 静的なデータも静的なメソッドも Python でサポー
トされています。

静的なデータを作るには、単純にクラス属性を定義してください。その属性に
新しい値を代入するには、代入するクラス名を明示する必要があります:

   class C:
       count = 0   # number of times C.__init__ called

       def __init__(self):
           C.count = C.count + 1

       def getcount(self):
           return C.count  # or return self.count

"c" そのものや "c.__class__" から "C" にいたるパス探索経路上のクラスに
よってオーバーライドされない限り、"c.count" も "isinstance(c, C)" であ
るすべての "c" に対する "C.count" を参照します。

注意: C のメソッド内では、"self.count = 42" のような代入は "self" 自身
の辞書に "count" という名前の新しくて関係ないインスタンスを作ります。
クラスの静的なデータの再束縛には、メソッド内であるか否かにかかわらず、
いつもクラスを指定しなければなりません:

   C.count = 314

Python 2.2 からは、静的メソッドが使えます:

   class C:
       def static(arg1, arg2, arg3):
           # No 'self' parameter!
           ...
       static = staticmethod(static)

Python 2.4 のデコレータを使って、以下のようにも書けます:

   class C:
       @staticmethod
       def static(arg1, arg2, arg3):
           # No 'self' parameter!
           ...

しかし、静的メソッドの効果を得るもっと簡単な方法は、単にモジュールレベ
ル関数を使うことです:

   def getcount():
       return C.count

モジュールあたりに一つのクラスを定義するように (あるいはクラス組織を厳
密に関連させるように) コードが構成されているなら、これで必要なカプセル
化ができます。


Python でコンストラクタ(やメソッド)をオーバーロードするにはどうしたらいいですか？
---------------------------------------------------------------------------------

この質問の答えはすべてのメソッドについて言えることですが、この質問はだ
いたい以下の構造の文脈から出てきます。

C++ では、このように書けます

   class C {
       C() { cout << "No arguments\n"; }
       C(int i) { cout << "Argument is " << i << "\n"; }
   }

Python では、一つのコンストラクタでデフォルトの引数を使ってすべての場
合に対応するように書かなければなりません。例えば:

   class C:
       def __init__(self, i=None):
           if i is None:
               print "No arguments"
           else:
               print "Argument is", i

これで完全に等価とは言えませんが、実用上は十分に近いです。

長さが変えられる引数のリストを試すには、例えば

   def __init__(self, *args):
       ...

これと同じやり方がすべてのメソッド定義で使えます。


__spam を使おうとしたら _SomeClassName__spam からエラーがでました。
-------------------------------------------------------------------

先頭にアンダースコアが二つ付いた変数名は、クラスのプライベートな変数を
、"マングル化"という単純かつ効率のいい方法で定義します。"__spam" のよ
うな形式 (先頭に二つ以上、末尾にもしあっても一つのアンダースコアがある
) のすべての識別子は、"classname" が先頭のアンダースコアをすべて削除し
た現在のクラス名とすれば、"_classname__spam" のように文字上で置換えら
れます。

これはプライベートであることを保証するものではありません。これでも外部
のユーザが "_classname__spam" 属性に直接アクセスできますし、プライベー
トな変数はオブジェクトの "__dict__" から見えます。多くの Python プログ
ラマはわざわざプライベートな変数名を使おうとなど考えません。


クラスに __del__ メソッドを定義しているのですが、オブジェクトを削除したときに呼ばれません。
-------------------------------------------------------------------------------------------

いくつかの可能性があります。

del 文は必ずしも "__del__()" を呼び出すとは限りません -- これは単純に
オブジェクトの参照カウントを減らすもので、カウントがゼロになったときに
"__del__()" が呼び出されます。

データ構造が循環リンク (子のそれぞれが親の参照を持ち、親のそれぞれが子
のリストを持つツリーなど) を含む場合、その参照カウントは決して 0 には
なりません。時々、Python はこのようなサイクルを検出するアルゴリズムを
実行しますが、データ構造への参照がなくなってからこのガベージコレクタが
実行されるまでいくらか時間が掛かるかもしれないので、 "__del__()" メソ
ッドは不都合な予期できないタイミングで呼び出されるかもしれません。これ
は問題を再現しようとするときに不便です。さらに悪いことに、オブジェクト
の "__del__()" メソッドが実行される順序は任意です。 "gc.collect()" を
起動して収集を強制することができますが、オブジェクトが決して回収されな
いような本当に病的な場合も *あります* 。

周期的なコレクタにかかわらず、オブジェクトに "close()" メソッドを明示
的に定義し、使い終わったらいつでも呼び出せるようにするのはいいことです
。そうすれば "close()" メソッドはサブオブジェクトへの参照をする属性を
取り除いてくれます。 "__del__()" を直接呼び出さないでください --
"__del__()" は "close()" を呼び出すでしょうし、 "close()" なら同じオブ
ジェクトに対して複数回呼ばれてもいいことが保証されているでしょう。

循環参照を避ける他の方法は、 "weakref" モジュールを使って、参照カウン
トを増やすことなくオブジェクトを示すことです。例えばツリー構造は、親と
(必要なら！) 兄弟に弱参照を使うべきです。

except 節で例外を捕まえた関数内でオブジェクトがローカル変数であったた
なら、そのオブジェクトへの参照が関数のスタックフレーム内でスタックトレ
ース内に含まれることで存在する可能性があります。通常、
"sys.exc_clear()" を呼び出せば、最後に記録された例外を消去することで対
処してくれます。

最後に、 "__del__()" メソッドが例外を発生させた場合、警告のメッセージ
が "sys.stderr" に書きこまれます。


与えられたクラスのすべてのインスタンスのリストを得るにはどうしますか？
----------------------------------------------------------------------

Python はクラス (やビルトイン型) のすべてのインスタンスをたどりません
。クラスのコンストラクタにそれぞれのインスタンスへの弱参照のリストを作
らせることですべてのインスタンスをたどらせられます。


なぜ "id()" の結果は一意でないように見えるのですか?
---------------------------------------------------

組み込みの "id()" は、オブジェクトが生きている間は一意であることが保証
されている整数値を返します。 CPython では、それはオブジェクトのメモリ
アドレスなので、オブジェクトがメモリから削除された後に、次に新しく生成
されたオブジェクトはメモリの同じ場所にメモリ領域を確保されていることが
、しばしば起きます。この現象を次の例で示しましょう:

>>> id(1000)
13901272
>>> id(2000)
13901272

2 つの同じ値を持つ id は "id()" の実行の前に作られてすぐさま削除された
異なる整数オブジェクトによるものです。id を調べたいオブジェクトがまだ
生きてることを保証したいなら、オブジェクトへの別の参照を作ってください
:

>>> a = 1000; b = 2000
>>> id(a)
13901272
>>> id(b)
13891296


モジュール
==========


.pyc ファイルを作るにはどうしますか？
-------------------------------------

モジュールが最初にインポートされるとき (またはソースが現在コンパイルさ
れているファイルよりも新しいとき)、コンパイルされたコードを含む ".pyc"
ファイルが ".py" ファイルと同じディレクトリに作られるでしょう。

".pyc" ファイルが作られないとしたら、ディレクトリの権限の問題があるか
もしれません。たとえばこれは、web サーバなどでテストするときのように、
開発のときと違うユーザとして起動するときなどに起こりえます。モジュール
をインポートしたときに Python がコンパイルされたモジュールをディレクト
リに書き込むための条件 (権限、容量の空き、etc...) が揃っていれば、.pyc
ファイルの生成は自動的に行われます。

トップレベルのスクリプトを実行することはインポートとは見做されず、
".pyc" は生成されません。例えば、トップレベルモジュール "abc.py" があ
って、他のモジュール "xyz.py" をインポートするようになっているとき、
abc を起動すると、xyz のインポート時に "xyz.pyc" が生成されますが、
"abc.py" はインポートされないので "abc.pyc" ファイルは生成されません。

abc.pyc が必要なら -- つまり、インポートされないモジュールの ".pyc" フ
ァイルを生成するためには -- "py_compile" や "compileall" モジュールが
利用できます。

"py_compile" モジュールは手動で任意のモジュールをコンパイルできます。
やり方の一つは、このモジュールの "compile()" 関数をインタラクティブに
実行することです:

   >>> import py_compile
   >>> py_compile.compile('foo.py')                 

このように実行すると、"foo.py" と同じ場所に ".pyc" が書き出されます (
出力ファイルの位置は、オプション引数 "cfile" で上書きすることもできま
す)。

"compileall" モジュールを使えば自動的に一つや複数のディレクトリのすべ
てのファイルをコンパイルできます。シェルプロンプトから "compileall.py"
を起動して、コンパイルしたいファイルを含むディレクトリのパスを指定して
ください:

   python -m compileall .


現在のモジュール名を知るにはどうしますか？
------------------------------------------

モジュールは前もって定義されたグローバル変数 "__name__" を検索すること
で自身の名前を決定できます。この値が "'__main__'" であるとき、そのプロ
グラムはスクリプトとして実行されています。インポートされることによって
使われる大抵のモジュールはコマンドラインインタフェースや自己テストも提
供していて、"__name__" をチェックしてからそのコードだけを実行します:

   def main():
       print 'Running test...'
       ...

   if __name__ == '__main__':
       main()


相互にインポートしあうモジュールを作るにはどうしたらいいですか？
----------------------------------------------------------------

以下のモジュールがあったとしましょう:

foo.py:

   from bar import bar_var
   foo_var = 1

bar.py:

   from foo import foo_var
   bar_var = 2

問題はインタプリタが以下の段階を実行することです:

* main が foo をインポートする

* foo の空のグローバルが生成される

* foo がコンパイルされ実行を始める

* foo が bar をインポートする

* bar の空のグローバルが生成される

* bar がコンパイルされ実行を始める

* bar が foo をインポートする(すでに foo という名前のモジュールがあ
  る ので no-op となる)

* bar.foo_var = foo.foo_var

この最後の段階は失敗します。Python が "foo" を解釈し終わっていなくて、
"foo" のグローバルなシンボルの辞書はまだ空ですから。

"import foo" を使って、グローバルコードの "foo.foo_var" にアクセスしよ
うとしたときにも、これと同じことが起こります。

この問題には (少なくとも) 三つの解決策があります。

Guido van Rossum は "from <module> import ..." を全く使わないで、すべ
てのコードを関数の中に入れることを勧めています。グローバル変数とクラス
変数の初期化は定数とビルトイン関数のみで行われるべきです。これでインポ
ートされたすべてのモジュールは "<module>.<name>" として参照されること
になります。

Jim Roskind はそれぞれのモジュールに対して以下の順に進めることを提案し
ています:

* エクスポート (インポートされた基底クラスを必要としないグローバル、
  関 数、クラス)

* "import" 文

* アクティブなコード (インポートされた値によって初期化されるグローバ
  ル を含む)。

インポートが奇妙な場所に現れることから van Rossum はこの方法をそれほど
好みませんが、これは有効です。

Matthias Urlichs は第一に再帰インポートが必要ないようにコードを構築し
なおすことを推奨しています。

これらの解決策はそれぞれ両立させることもできます。


__import__('x.y.z') は <module 'x'> を返しますが、z を得るためにはどうしますか？
--------------------------------------------------------------------------------

mod:*importlib* に "import_module()" という便利な関数があるので、代わ
りにそちらを使用することを検討してください。

   z = importlib.import_module('x.y.z')


インポートされたモジュールを編集してから再インポートしましたが、変化が現れません。なぜですか？
----------------------------------------------------------------------------------------------

効率と一貫性上の理由から、Python はモジュールが最初にインポートされた
時にのみモジュールファイルを読み込みます。そうしないと、たくさんのモジ
ュールでできていて、それぞれが同じ基本モジュールをインポートしているよ
うなプログラムでは、その基本モジュールの解析と再解析が繰り返されること
になります。変更されさたモジュールの再読込を強制するには、こうしてくだ
さい:

   import modname
   reload(modname)

注意:この手法は 100%安全とは言えません。とりわけ

   from modname import some_objects

のような文を含むモジュールは、インポートされたオブジェクトの古いバージ
ョンを使い続けます。そのモジュールにクラス定義が含まれていたら、存在す
るクラスインスタンスは新しいクラス定義を使うようにアップデート *されま
せん*。これによって以下の矛盾した振舞いがなされえます:

>>> import cls
>>> c = cls.C()                # Create an instance of C
>>> reload(cls)
<module 'cls' from 'cls.pyc'>
>>> isinstance(c, cls.C)       # isinstance is false?!?
False

この問題の本質は、クラスオブジェクトを印字することで明らかになります:

>>> c.__class__
<class cls.C at 0x7352a0>
>>> cls.C
<class cls.C at 0x4198d0>
