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


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


ブレークポイントやステップ実行ができる、ソースコードレベルのデバッガはありますか？
----------------------------------------------------------------------------------

はい。

Python 用のデバッガについては次に解説してあり、組み込みの
"breakpoint()" 関数でそれらのデバッガに処理を移せます。

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

IDLE 対話型開発環境は、標準 Python ディストリビューションの一部 (普通
は "idlelib" として利用可能) であり、グラフィカルなデバッガを含んでい
ます。

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

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

trepan3k は gdbライクなデバッガです。

Visual Studio Code はバージョン管理ソフトと一緒になったデバッグツール
を備えた IDE です

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

* Wing IDE

* PyCharm


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

はい。

Ruff, Pylint と Pyflakes は、基本的なチェックを行いバグの早期発見を助
けます。

mypy, ty, Pyrefly, そして pytype などの静的型チェッカーは、 Python ソ
ースコードにある型ヒントをチェックできます。


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

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

ひとつは freeze ツールを使うことですが、これはPython ソースツリーに
Tools/freeze として含まれています。これは Python バイトコードを C 配列
に変換します。併せて C コンパイラを使うと あなたの全モジュールを新しい
プログラムに埋め込み、それを Python 標準モジュールにリンクすることがで
きます。

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

以下のパッケージはコンソールやGUIの実行ファイル作成に役立ちます。

* Nuitka (Cross-platform)

* PyInstaller (Cross-platform)

* PyOxidizer (Cross-platform)

* cx_Freeze (Cross-platform)

* py2app (macOS only)

* py2exe (Windows only)


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

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


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


なぜ変数に値があるのに 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: cannot access local variable 'x' where it is not associated with a value

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

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

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

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

>>> print(x)
11

同様のことを、ネストされたスコープで "nonlocal" 予約語を使うことでもで
きます:

>>> def foo():
...    x = 10
...    def bar():
...        nonlocal x
...        print(x)
...        x += 1
...    bar()
...    print(x)
...
>>> foo()
10
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   # 'x' 設定のデフォルト値

mod.py:

   import config
   config.x = 1

main.py:

   import config
   import mod
   print(config.x)

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


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

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

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

次の手順でモジュールをインポートするのが、良い習慣になります:

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

2. サードパーティのライブラリモジュール (Python の site-packages ディ
   レクトリにインストールされているもの) -- 例 dateutil, requests,
   tzdata

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

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

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

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

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

インポートを関数定義内などのローカルスコープへ移すのは、循環インポート
を避けるといった問題の解決に必要な場合や、モジュールの初期化時間を短く
したい場合だけにしてください。 この手法は、プログラムの実行のされ方に
よって多くのインポートが不要になる場合に特に有効です。 モジュールをあ
る関数の中でしか使わない場合も、インポートをその関数内へ移すとよいでし
ょう。 初回の読み込みにはモジュールの初期化が伴うため、時間がかかるこ
とがあります。 一方、繰り返し読み込むときのコストは辞書を数回検索する
程度で、ほぼ無視できます。 モジュール名がスコープから外れても、モジュ
ール自体はおそらく "sys.modules" に残っています。


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

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

   def foo(mydict={}):  # 危険：すべての呼び出しで単一辞書への参照が共有される
       ... 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 = {}  # ローカル名前空間での新辞書作成

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

   # 呼び出し元は２つのパラメータを指定でき、キーワードにより _cache をオプションとして渡せる
   def expensive(arg1, arg2, *, _cache={}):
       if (arg1, arg2) in _cache:
           return _cache[(arg1, arg2)]

       # 値の算出
       result = ... 高コストな計算 ...
       _cache[(arg1, arg2)] = result           # 結果をキャッシュに保持
       return result

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


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

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

   def f(x, *args, **kwargs):
       ...
       kwargs['width'] = '14.3c'
       ...
       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  # int はイミュータブル（不変）
   >>> y = x
   >>> x = x + 1  # 5 は変更不可。 ここでは新しいオブジェクトを作っている
   >>> 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" は新しいオブジェクトを作ります)。

言い換えると:

* mutable オブジェクト ("list", "dict", "set" のような) の場合は、特定
  の操作を用いてそれを変えることができ、それを参照する どの変数にも そ
  の変更が反映されます。

* immutable オブジェクト ("str", "int", "tuple" のような) の場合は、そ
  れを参照する どの変数も同じ値を参照しますが、その値を新しい値に変換
  する操作では 常に新しいオブジェクトを返します。

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


出力引数のある関数 (参照渡し) はどのように書きますか？
------------------------------------------------------

Pythonにおける実引数は代入にて渡されることと留意してください。 代入は
オブジェクトへの参照を作るだけなので、呼び出し元/先での引数名の間にエ
イリアスは存在せず、従って参照渡しになりません。 目的の動作を実現する
には、いくつか方法があります。

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

      >>> def func1(a, b):
      ...     a = 'new-value'        # a と b はローカル名で
      ...     b = b + 1              # 新しいオブジェクトが代入され
      ...     return a, b            # 新しい値一式を返す
      ...
      >>> x, y = 'old-value', 99
      >>> func1(x, y)
      ('new-value', 100)

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

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

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

      >>> def func2(a):
      ...     a[0] = 'new-value'     # 'a' は mutable list への参照
      ...     a[1] = a[1] + 1        # 共有されたオブジェクトを変える
      ...
      >>> args = ['old-value', 99]
      >>> func2(args)
      >>> args
      ['new-value', 100]

4. 変更を受ける辞書を渡すことによって:

      >>> def func3(args):
      ...     args['a'] = 'new-value'     # args は mutable dictionary
      ...     args['b'] = args['b'] + 1   # インプレースで変更
      ...
      >>> args = {'a': 'old-value', 'b': 99}
      >>> func3(args)
      >>> args
      {'a': 'new-value', 'b': 100}

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

      >>> class Namespace:
      ...     def __init__(self, /, **args):
      ...         for key, value in args.items():
      ...             setattr(self, key, value)
      ...
      >>> def func4(args):
      ...     args.a = 'new-value'        # args は mutable Namespace
      ...     args.b = args.b + 1         # オブジェクトをインプレースで変更
      ...
      >>> args = Namespace(a='old-value', b=99)
      >>> func4(args)
      >>> vars(args)
      {'a': 'new-value', 'b': 100}

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

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


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__ 継承
       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 object at 0x16D07CC>
   >>> print(a)
   <__main__.A object at 0x16D07CC>

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

概して、コードにとってある値の「名前を知っている」事は重要ではありませ
ん。あなたがあえて introspective （訳注：実行時のオブジェクト情報を調
査するような）プログラムを書いているのでない限り、方針を変えた方がいい
かもしれないということになるでしょう。

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

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

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


カンマ演算子の優先順位はどうなっていますか？
--------------------------------------------

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

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

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

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

こうではありません:

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

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


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

はい、あります。構文は以下のようになります:

   [on_true] if [expression] else [on_false]

   x, y = 50, 25
   small = x if x < y else y

この構文が導入された 2.5 以前のバージョンに関しては、論理演算子を使っ
たこのイディオムが一般的でした:

   [expression] and [on_true] or [on_false]

しかし、このイディオムは安全ではありません。*on_true* のブール値が偽で
あるときに間違った結果を与えることがあります。ですから、いつでも "...
if ... else ..." 形式を使ったほうが良いです。


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

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

   from functools import reduce

   # 素数 < 1000
   print(list(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)))))

   # 先頭 10 フィボナッチ数列
   print(list(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))))

   # マンデルブロ集合
   print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+'\n'+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))
   #    \___ ___/  \___ ___/  |   |   |__ 画面行数
   #        V          V      |   |______ 画面列数
   #        |          |      |__________ 最大 "iterations"
   #        |          |_________________ y 軸範囲
   #        |____________________________ x 軸範囲

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


関数の仮引数リストにあるスラッシュ (/) は何を意味しますか？
-----------------------------------------------------------

関数の仮引数にあるスラッシュは、それより前にある仮引数は位置専用引数で
あることを示します。 位置専用引数は、外から使える名前を持たない仮引数
です。 位置専用引数を受け付ける関数の呼び出しにおいて、実引数はその位
置だけに基づいて仮引数に対応付けられます。 例えば、 "divmod()" は位置
専用引数を受け付けます。 そのドキュメントは次のようになります:

   >>> help(divmod)
   Help on built-in function divmod in module builtins:

   divmod(x, y, /)
       Return the tuple (x//y, x%y).  Invariant: div*y + mod == x.

この引数リストの末尾にスラッシュは、この2つの仮引数が両方とも位置専用
引数であることを意味します。 したがって、"divmod()" をキーワード引数を
使って呼び出すとエラーになります:

   >>> divmod(x=3, y=4)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: divmod() takes no keyword arguments


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


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

八進数を指定するには、八進数での値の先頭に 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 でもこ
の等式を満たす必要があり、商をゼロ方向に切り捨てるコンパイラでは、"i %
j" の符号を "i" と同じにする必要があります。

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


どうすれば SyntaxError を起こさずに整数リテラルの属性を得られますか？
---------------------------------------------------------------------

ふつうの方法で "int" リテラルの属性を探そうとすると、ピリオドが小数点
とみなされ、"SyntaxError" となります:

   >>> 1.__class__
     File "<stdin>", line 1
     1.__class__
      ^
   SyntaxError: invalid decimal literal

解決策は、リテラルとピリオドを スペースや括弧で分けることです。

>>> 1 .__class__
<class 'int'>
>>> (1).__class__
<class 'int'>


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

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

デフォルトでは、これらは数を十進数として解釈するので、 "int('0144') ==
144" は成立しますが "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' 以外の) 十進数を
'0' で始めてはならないからです。


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

例えば、"144" という数を "'144'" という文字列に変換したいなら、組み込
み型のコンストラクタ "str()" を使ってください。 十六進数や八進数にした
ければ、組み込み関数の "hex()" や "oct()" を使ってください。 手の込ん
だフォーマット形式を使うなら、 f-strings と 書式文字列の構文 の節を参
照してください。 例えば、 ""{:04d}".format(144)" は "'0144'" になり、
""{:.3f}".format(1.0/3.0)" は "'0.333'" になります。


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

文字列はイミュータブルなので、それはできません。殆どの場合、組み立てた
い個別の部品から単純に新しい文字列を構成するべきです。しかし、 Unicode
データをインプレースに変更できるオブジェクトが必要なら、 "io.StringIO"
オブジェクトや "array" モジュールを試してください:

   >>> import io
   >>> s = "Hello, world"
   >>> sio = io.StringIO(s)
   >>> sio.getvalue()
   'Hello, world'
   >>> sio.seek(7)
   7
   >>> sio.write("there!")
   6
   >>> sio.getvalue()
   'Hello, there!'

   >>> import array
   >>> a = array.array('w', s)
   >>> print(a)
   array('w', 'Hello, world')
   >>> a[0] = 'y'
   >>> print(a)
   array('w', 'yello, world')
   >>> a.tounicode()
   'yello, world'


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

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

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

     def a():
         pass

     def b():
         pass

     dispatch = {'go': a, 'stop': b}  # 注意：関数にはカッコなし

     dispatch[get_input()]()  # 注意：関数を呼び出すには末尾カッコ

* 組み込み関数の "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()" を使って関数名を決める方法:

     def myFunc():
         print("hello")

     fname = "myFunc"

     f = locals()[fname]
     f()


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

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

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

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


"scanf()" や "sscanf()" に相当するものはありますか？
----------------------------------------------------

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

単純な入力を解析するには、通常、文字列オブジェクトの "split()" メソッ
ドで行を空白区切りの単語に分割し、"int()" や "float()" で十進数の文字
列を数値に変換するのが最も簡単です。 "split()" には省略可能な "sep" 引
数があり、空白以外の区切り文字を使った行を扱うのに便利です。

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


"UnicodeDecodeError" や "UnicodeEncodeError" は何を意味しますか？
-----------------------------------------------------------------

Unicode HOWTO を参照して下さい。


raw string を奇数個のバックスラッシュで終えることはできますか？
---------------------------------------------------------------

奇数個のバックスラッシュで終わる raw string は文字列のクォートをエスケ
ープします:

   >>> r'C:\this\will\not\work\'
     File "<stdin>", line 1
       r'C:\this\will\not\work\'
       ^
   SyntaxError: unterminated string literal (detected at line 1)

これにはいくつかの回避策があります。ひとつは通常文字列と二重バックスラ
ッシュを使うことです:

   >>> 'C:\\this\\will\\work\\'
   'C:\\this\\will\\work\\'

もうひとつは、エスケープされたバックスラッシュを含む通常の文字列を、
raw string に連結します:

   >>> r'C:\this\will\work' '\\'
   'C:\\this\\will\\work\\'

Windowsでは、 "os.path.join()" を使ってバックスラッシュを追加すること
もできます:

   >>> os.path.join(r'C:\this\will\work', '')
   'C:\\this\\will\\work\\'

注意点として、バックスラッシュは raw string 終端のクォートを「エスケー
プ」しますが、 raw string の値を解釈する際にはエスケープが生じません。
つまり、バックスラッシュは raw string 値の中に残ったままになります:

   >>> r'backslash\'preserved'
   "backslash\\'preserved"

言語リファレンス の仕様も参照してください。


性能
====


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

一般には難しい問題です。 詳しく検討する前に、まず次の点を覚えておいて
ください。

* 性能の傾向は Python 実装によって変わります。この FAQ では *CPython*
  に焦点を当てます。

* 振る舞いはオペレーティングシステムによって変わりえます。特に、I/O や
  マルチスレッドに関しては顕著です。

* 常に、コードの最適化を始める *前に* プログラムのホットスポットを見つ
  けるべきです ("profile" モジュールを参照してください)。

* ベンチマークスクリプトを書くことで、改善箇所の捜索を素早く繰り返せま
  す ("timeit" モジュールを参照してください)。

* 洗練された最適化に隠れたリグレッションの可能性を生む前に、(ユニット
  テストやその他の技法で) コードカバレッジを上げることを強く推奨します
  。

とはいえ、Python コードを高速化する方法はたくさんあります。 満足できる
性能を得るうえで大いに役立つ一般的な方針を紹介します。

* コード中に細かい最適化の技法をばらまこうとするよりも、アルゴリズムを
  高速化 (または高速なアルゴリズムに変更) するほうが、大きな利益を生む
  ことがあります。

* 適切なデータ構造を使ってください。組み込み型 や "collections" を調べ
  てください。

* 何かをするための基本要素が標準ライブラリにあるなら、自分で発明した代
  用品よりもそちらのほうが、(絶対にとは言えませんが) おそらく速いです
  。 それが組み込み型やある種の拡張型のように C で書かれたものならなお
  さらです。 たとえば、ソートするには、必ず "list.sort()" 組み込みメソ
  ッドか "sorted()" 関数を使ってください (また、中程度に高度な例は、
  ソートのテクニック を参照してください)。

* 抽象化によって処理が間接的になると、インタープリタの仕事が増えがちで
  す。 間接的な処理の負担が本来の処理の量を上回ると、プログラムが遅く
  なります。 過度な抽象化、特に細かすぎる関数やメソッドは避けるべきで
  す。 こうした関数やメソッドは、読みやすさを損なうこともよくあります
  。

Python だけで書いたコードの限界に達したら、さらに性能を上げるためのツ
ールがあります。 例えば Cython は、Python コードに少し手を加えたものを
C 拡張にコンパイルでき、多くのプラットフォームで使えます。 Cython はコ
ンパイルと、省略可能な型アノテーションを活用することで、インタープリタ
による実行よりもコードを大幅に高速化できます。 C のプログラミングに自
信があれば、自分で C 拡張モジュールを書く こともできます。

参考: パフォーマンス tips が載っている wiki のページ。


多くの文字列を結合するのに最も効率的な方法は何ですか？
------------------------------------------------------

"str" と "bytes" のオブジェクトはイミュータブルなので、多数の文字列を
連結すると、そのたびに新しいオブジェクトが作られて非効率になります。
一般には、実行時間は文字列の全長の二乗に比例します。 詳しくは 組み込み
型の操作の時間計算量 を参照してください。

多くの "str" オブジェクトを累積するのにおすすめのイディオムは、すべて
をリストに配置してから最後に "str.join()" を呼び出すことです:

   chunks = []
   for s in my_strings:
       chunks.append(s)
   result = ''.join(chunks)

("io.StringIO" を使うのも、ある程度効率のよい方法です。)

多くの "bytes" オブジェクトを累積するのにおすすめのイディオムは、
"bytearray" オブジェクトをインプレース結合 ("+=" 演算子) で拡張するこ
とです:

   result = bytearray()
   for b in my_bytes_objects:
       result += b


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


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

型コンストラクタ "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]" は文字列
の最後以外のすべての文字を表すので、文字列の末尾の改行を取り除くときに
便利です。


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

組み込み関数 "reversed()" を使ってください。

   for x in reversed(sequence):
       ...  # 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* な場合) は、次の方法のほうが速いことがよくあります。

   mylist = list(set(mylist))

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


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

重複を取り除く場合と同じように、逆順にイテレートし、条件に合う要素を削
除する方法があります。 ただし、暗黙的または明示的に順方向へイテレート
し、スライスを置き換えるほうが簡単で高速です。 次の 3 通りの書き方があ
ります。

   mylist[:] = filter(keep_function, mylist)
   mylist[:] = (x for x in mylist if keep_condition)
   mylist[:] = [x for x in mylist if keep_condition]

リスト内包表記がおそらく最も高速です。


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

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

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

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

"array" モジュールにも、型を固定した配列をコンパクトな表現で作るための
メソッドがありますが、インデックスによるアクセスはリストより遅くなりま
す。 また、NumPy などのサードパーティーパッケージも、さまざまな特性を
持つ配列に似た構造を定義しています。

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

   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 の同じリストへの参照を 3 つ含む
リストを作ります。 1 つの行を変更するとすべての行に反映されますが、こ
れが意図した結果であることはまずないでしょう。

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

   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 が最もよく知られています。


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

メソッドや関数を呼び出し、その戻り値をリストにまとめるには、*list
comprehension* を使うと簡潔に書けます。

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

   result = [function(obj) for obj in mylist]

戻り値を保存せずにメソッドや関数を実行するだけなら、ただの "for" ルー
プで十分です:

   for obj in mylist:
       obj.method()

   for obj in mylist:
       function(obj)


なぜ加算はされるのに 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

例外の理由は明らかでしょう。 "a_tuple[0]" が指すオブジェクト ("1") に
"1" を加えると、結果のオブジェクト "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]" が既に指しているオブジェクトと同じオブジェクトを指してい
たとしても、タプルは不変なので、その最後の代入はやはりエラーとなります
。


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

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

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


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

2 つのリストをタプルのイテレータにまとめ、その結果から得られるリストを
ソートして、必要な要素を取り出してください。

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


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


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

クラスは class 文の実行によって作られる、特定の種類のオブジェクトです
。 クラスオブジェクトはインスタンスオブジェクトを作るためのテンプレー
トとして使われます。 インスタンスオブジェクトは、そのデータ型に固有の
データ (属性) とコード (メソッド) の両方を備えています。

新しいクラスを一つ以上の他のクラス (新しいクラスの基底クラスと呼ばれま
す) に基づいて作ることもできます。この新しいクラスは、基底クラスから属
性とメソッドを継承します。これにより、オブジェクトモデルを継承で連続的
に洗練できます。メールボックスへの基本的なアクセサを提供する一般的な
"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, ...))" のように、クラスを 1 つ渡す代
わりにタプルを渡すと、複数のクラスのいずれかのインスタンスであるかを調
べられます。 また、"isinstance(obj, str)" や "isinstance(obj, (int,
float, complex))" のように、Python の組み込み型のインスタンスであるか
も調べられます。

"isinstance()" は *abstract base class* の仮想的な継承も調べます。 そ
のため、抽象基底クラスに登録されたクラスであれば、直接または間接的に継
承していなくても "True" を返します。 「実際の継承」を調べるには、その
クラスの *method resolution order* (MRO) を確認します。

   from collections.abc import Mapping

   class P:
        pass

   class C(P):
       pass

   Mapping.register(P)

   >>> c = C()
   >>> isinstance(c, C)        # 直接
   True
   >>> isinstance(c, P)        # 間接
   True
   >>> isinstance(c, Mapping)  # 仮想
   True

   # 実際の継承関係
   >>> type(c).__mro__
   (<class 'C'>, <class 'P'>, <class 'object'>)

   # 「実際の継承」を調べる
   >>> Mapping in type(c).__mro__
   False

なお、ほとんどのプログラムでは、ユーザー定義のクラスに対して
"isinstance()" を頻繁には使いません。 自分でクラスを開発するなら、オブ
ジェクトのクラスを調べて処理を分岐させるよりも、各クラスに特定の振る舞
いをカプセル化するメソッドを定義するほうが、オブジェクト指向に適した書
き方です。 例えば、次のような関数があるとします。

   def search(obj):
       if isinstance(obj, Mailbox):
           ...  # メールボックスを検索するコード
       elif isinstance(obj, Document):
           ...  # 文書を検索するコード
       elif ...

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

   class Mailbox:
       def search(self):
           ...  # メールボックスを検索するコード

   class Document:
       def search(self):
           ...  # 文書を検索するコード

   obj.search()


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

委譲はオブジェクト指向の技法 (デザインパターンとも呼ばれます) の 1 つ
です。 オブジェクト "x" があり、そのメソッドのうち 1 つだけ振る舞いを
変えたいとします。 そのメソッドの新しい実装を持ち、ほかのすべてのメソ
ッドの処理を "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" の属性を
設定するため、"object.__setattr__()" を呼び出します。

   class X:
       def __setattr__(self, name, value):
           # ここに独自の処理を書く...
           object.__setattr__(self, name, value)

"self.__dict__" に直接エントリーを追加して属性を設定することもできます
。


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

組み込みの "super()" 関数を使ってください:

   class Derived(Base):
       def meth(self):
           super().meth()  # Base.meth を呼び出す

この例では、 "super()" は呼ばれたインスタンス ("self" の値) を自動判断
し、 "type(self).__mro__" で *method resolution order* (MRO メソッド解
決順) を検索し、MRO で "Derived" の次にある "Base" を返します。


基底クラスを変更しやすいようにコードを構成するにはどうしますか？
----------------------------------------------------------------

基底クラスを別名に代入し、その別名を使って継承できます。 こうすれば、
別名に代入する値だけを変更すれば済みます。 この方法は、例えばリソース
が利用できるかどうかに応じて、使う基底クラスを動的に決めたい場合にも便
利です。

   class Base:
       ...

   BaseAlias = Base

   class Derived(BaseAlias):
       ...


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

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

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

   class C:
       count = 0   # C.__init__ が呼び出された回数

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

       def getcount(self):
           return C.count  # または return self.count

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

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

   C.count = 314

静的メソッドが使えます:

   class C:
       @staticmethod
       def static(arg1, arg2, arg3):
           # 'self' 仮引数はない！
           ...

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

   def getcount():
       return C.count

モジュールごとに 1 つのクラス、または密接に関連するクラス階層を定義す
る構成なら、この方法で必要なカプセル化を実現できます。


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" のように文字上で置換え
られます。

クラス内では識別子をそのまま使えますが、クラス外からアクセスするにはマ
ングル化された名前を使う必要があります。

   class A:
       def __one(self):
           return 1
       def two(self):
           return 2 * self.__one()

   class B(A):
       def three(self):
           return 3 * self._A__one()

   four = 4 * A()._A__one()

特に、この仕組みはプライバシーを保証するものではありません。 外部の利
用者が意図的にプライベート属性にアクセスすることは可能です。 Python プ
ログラマの多くは、プライベートな変数名をあえて使うことはしません。

参考: 詳細と特例は、 private name mangling specifications 。


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

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

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

データ構造に循環参照があると、参照カウントはゼロに戻りません。 例えば
、各子が親への参照を持ち、各親が子のリストを持つツリーがこれに当たりま
す。 Python はこうした循環を検出するアルゴリズムを時折実行しますが、デ
ータ構造への最後の参照がなくなってからガベージコレクタが動くまでには、
時間がかかる場合があります。 そのため、"__del__()" メソッドが都合の悪
い、予測できないタイミングで呼ばれることがあります。 これは問題を再現
しようとするときに不便です。 さらに、オブジェクトの "__del__()" メソッ
ドの実行順序は任意です。 "gc.collect()" を実行して回収を強制できますが
、オブジェクトが決して回収されない特殊な場合も *あります*。

循環参照を回収する仕組みがあっても、オブジェクトには明示的な "close()"
メソッドを定義し、使い終わったときに呼び出すようにするとよいでしょう。
"close()" メソッドでは、下位のオブジェクトを参照する属性を削除できます
。 "__del__()" を直接呼び出さないでください。 "__del__()" から
"close()" を呼び出し、"close()" は同じオブジェクトに対して複数回呼び出
せるように実装してください。

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

最後に、 "__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


いつ *is* 演算子での同一性テストが頼れますか？
----------------------------------------------

"is" 演算子はオブジェクトの同一性をテストします。  テスト "a is b" は
"id(a) == id(b)" と同等です。

同一性テストの最も重要な特性は、オブジェクトは常にそれ自身と同一であり
、 "a is a" は常に "True" を返すということです。  同一性テストは通常、
等価性テストよりも高速です。  また、等価性テストとは異なり、同一性テス
トは真偽値 "True" または "False" を返すことが保証されています。

ただし、同一性テストを等価性テストの代用とできるのは、オブジェクトの同
一性が保証されている場合 *のみ* です。  一般的に、同一性が保証される状
況は3つあります:

1. 代入は新しい名前を作りますが、オブジェクトの同一性は変えません。
   "new = old" と代入した後は、"new is old" が保証されます。

2. オブジェクトへの参照を格納するコンテナにオブジェクトを入れても、そ
   の同一性は変わりません。 リストへの代入 "s[0] = x" の後は、"s[0] is
   x" が保証されます。

3. シングルトンのオブジェクトは、インスタンスが 1 つしか存在できません
   。 "None" はシングルトンなので、"a = None" と "b = None" を代入した
   後は、"a is b" が保証されます。

多くの他の状況では、同一性テストは賢明でなく、等価性テストをお勧めしま
す。  特に、シングルトンであることが保証されていない "int" や "str" な
どの定数をチェックするために同一性テストを使わないでください。

   >>> a = 10_000_000
   >>> b = 5_000_000
   >>> c = b + 5_000_000
   >>> a is c
   False

   >>> a = 'Python'
   >>> b = 'Py'
   >>> c = b + 'thon'
   >>> a is c
   False

同様に、ミュータブルなコンテナの新しいインスタンスは同一ではありません
:

   >>> a = []
   >>> b = []
   >>> a is b
   False

標準ライブラリのコードには、同一性テストを正しく使うための一般的なパタ
ーンがあります:

1. **PEP 8** が推奨するとおり、"None" かどうかを調べるには同一性テスト
   を使うのが望ましい方法です。 コードを自然な英語として読めるうえ、真
   偽値が偽と評価されるほかのオブジェクトとの混同も避けられます。

2. オプション引数の検出は、 "None" が有効な入力値である場合に厄介なこ
   とになる場合があります。この状況では、他のオブジェクトと必ず区別で
   きる唯一のマーカーオブジェクト（ singleton sentinel object ）を作る
   ことで対策できます。例えば、 "dict.pop()" のように振る舞うメソッド
   を実装する方法を示します:

      _sentinel = sentinel('_sentinel')

      def pop(self, key, default=_sentinel):
          if key in self:
              value = self[key]
              del self[key]
              return value
          if default is _sentinel:
              raise KeyError(key)
          return default

3. コンテナの実装では、等価性テストを同一性テストで補強する必要がある
   場合があります。これは、 "float('NaN')" のような自分自身と等しくな
   いオブジェクトによってコードが混乱するのを防ぎます。

例えば、"collections.abc.Sequence.__contains__()" の実装は次のとおりで
す。

   def __contains__(self, value):
       for v in self:
           if v is value or v == value:
               return True
       return False


どうすればサブクラスはイミュータブルなインスタンスに格納されたデータを制御できますか？
--------------------------------------------------------------------------------------

イミュータブルな型のサブクラスを作る場合は、"__init__()" ではなく
"__new__()" メソッドをオーバーライドしてください。 "__init__()" が実行
されるのはインスタンスが作られた *後* なので、イミュータブルなインスタ
ンスのデータを変更するには遅すぎます。

これらのイミュータブルクラスはすべて、親クラスと異なるシグネチャを持ち
ます:

   import datetime as dt

   class FirstOfMonthDate(dt.date):
       "常にその月の初日を選ぶ"
       def __new__(cls, year, month, day):
           return super().__new__(cls, year, month, 1)

   class NamedInt(int):
       "一部の数値を文字列の名前で指定できるようにする"
       xlat = {'zero': 0, 'one': 1, 'ten': 10}
       def __new__(cls, value):
           value = cls.xlat.get(value, value)
           return super().__new__(cls, value)

   class TitleStr(str):
       "文字列を URL パスに適した名前に変換する"
       def __new__(cls, s):
           s = s.lower().replace(' ', '-')
           s = ''.join([c for c in s if c.isalnum() or c == '-'])
           return super().__new__(cls, s)

クラスはこのように使えます:

   >>> FirstOfMonthDate(2012, 2, 14)
   FirstOfMonthDate(2012, 2, 1)
   >>> NamedInt('ten')
   10
   >>> NamedInt(20)
   20
   >>> TitleStr('Blog: Why Python Rocks')
   'blog-why-python-rocks'


メソッド呼び出しをキャッシュするには どうしたらいいですか？
-----------------------------------------------------------

メソッドのキャッシュに使う主なツールは "@functools.cached_property" と
"@functools.lru_cache" です。 前者はインスタンス単位で、後者はクラス単
位で結果を保存します。

"cached_property" は、引数を受け取らないメソッドにだけ使えます。 イン
スタンスへの参照は作りません。 キャッシュされたメソッドの結果は、イン
スタンスが生存している間だけ保持されます。

利点は、インスタンスが使われなくなった場合、キャッシュされたメソッドの
結果がすぐに解放されることです。欠点は、インスタンスが溜まると、溜めら
れたメソッドの結果も増えてしまうことです。それらは際限なく増える恐れが
あります。

"lru_cache" は、引数が *hashable* なメソッドに使えます。 弱参照を渡す
ように特別な工夫をしない限り、インスタンスへの参照を作ります。

LRU (最も長く使われていないものから削除する) アルゴリズムの利点は、指
定された *maxsize* でキャッシュの大きさを制限できることです。 欠点は、
長く使われずにキャッシュから追い出されるか、キャッシュが消去されるまで
、インスタンスが生存し続けることです。

この例は各種テクニックを示します:

   class Weather:
       "政府のウェブサイトで気象情報を調べる"

       def __init__(self, station_id):
           self._station_id = station_id
           # _station_id はプライベートで変更されない

       def current_temperature(self):
           "1 時間ごとの観測の最新値"
           # 古い結果は現在の状況を反映しないことがあるので、
           # キャッシュしない。

       @cached_property
       def location(self):
           "観測所の経度・緯度を返す"
           # 結果は station_id だけに依存する

       @lru_cache(maxsize=20)
       def historic_rainfall(self, date, units='mm'):
           "指定した日の降水量"
           # station_id、date、units に依存する。

上の例は *station_id* が変わらないことを前提としています。 関係するイ
ンスタンス属性が変更される場合、"cached_property" は属性の変更を検出で
きないため、この方法は使えません。

To make the "lru_cache" approach work when the *station_id* is
mutable, the class needs to define the "__eq__()" and "__hash__()"
methods so that the cache can detect relevant attribute updates:

   class Weather:
       "Example with a mutable station identifier"

       def __init__(self, station_id):
           self.station_id = station_id

       def change_station(self, station_id):
           self.station_id = station_id

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

       def __hash__(self):
           return hash(self.station_id)

       @lru_cache(maxsize=20)
       def historic_rainfall(self, date, units='cm'):
           'Rainfall on a given date'
           # Depends on the station_id, date, and units.


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


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

モジュールが初めてインポートされたとき (もしくは、現在のコンパイルされ
たファイルが作られてから、ソースファイルが変更されたとき) 、コンパイル
されたコードが入っている ".pyc" ファイルが、 ".py" ファイルのあるディ
レクトリのサブディレクトリ "__pycache__" に作成されます。 ".pyc" ファ
イルのファイル名は、 ".py" ファイルの名前で始まり、 ".pyc" で終わり、
中間部分はこのファイルを作った "python" バイナリに依存した文字列になり
ます。 (詳細は **PEP 3147** を参照してください。)

".pyc" が作られない理由の 1 つは、ソースファイルがあるディレクトリの権
限の問題、つまり "__pycache__" サブディレクトリが作れない問題です。こ
れは、例えば、ウェブサーバーでテストを行っているときのような、開発者の
ユーザと実行者のユーザが別な場合に、起こり得ます。

"PYTHONDONTWRITEBYTECODE" 環境変数が設定されておらず、Python が
"__pycache__" サブディレクトリを作成してコンパイル済みモジュールを書き
込めるだけの権限や空き容量などを持っていれば、モジュールをインポートす
ると .pyc ファイルは自動的に作られます。

Python で最上位のスクリプトを実行することはインポートとはみなされず、
".pyc" は作られません。 例えば、最上位のモジュール "foo.py" が別のモジ
ュール "xyz.py" をインポートするとします。 シェルで "python foo.py" と
入力して "foo" を実行すると、"xyz" はインポートされるため ".pyc" が作
られますが、"foo.py" はインポートされないため "foo" の ".pyc" は作られ
ません。

"foo" の ".pyc" ファイルを作成する -- つまり、インポートされていないモ
ジュールの ".pyc" ファイルを作成する -- 必要がある場合、 "py_compile"
モジュールと "compileall" モジュールを使えば可能です。

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

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

これにより、"foo.py" と同じ場所にある "__pycache__" サブディレクトリに
".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 となる)

* インポートメカニズムは "foo" のグローバルから "foo_var" を読んで、
  "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 を得るためにはどうしますか？
--------------------------------------------------------------------------------

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

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


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

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

   import importlib
   import modname
   importlib.reload(modname)

注意: この方法は万全ではありません。 特に、

   from modname import some_objects

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

   >>> import importlib
   >>> import cls
   >>> c = cls.C()                # C のインスタンスを作る
   >>> importlib.reload(cls)
   <module 'cls' from 'cls.py'>
   >>> isinstance(c, cls.C)       # isinstance が偽になる！
   False

クラスオブジェクトの「識別値」を表示すると、この問題の原因がはっきりし
ます。

   >>> hex(id(c.__class__))
   '0x7352a0'
   >>> hex(id(cls.C))
   '0x4198d0'
