Commits

Naoki INADA committed db89709

module を追加

Comments (0)

Files changed (3)

    container.rst
    function.rst
    class.rst
+   module.rst
 ipython の代わりに bpython を使うか、 ``easy_install readline`` して、 Mac でも動く
 readline をインストールしてください。
 
+.. note::
+
+    カラム: easy_install と pip
+
+    virtualenv を使うと、 easy_install に加えて pip というツールもインストールされます。
+
+    easy_install は昔から使われているツールで、インストールするパッケージが依存している
+    パッケージも芋づる式にインストールしてくれます。
+
+    pip は最近良く使われるようになったツールで、依存パッケージのインストールに加えて、
+    ``pip freeze`` でインストールしたパッケージ一覧を表示したり、その一覧をテキストファイル
+    (慣習的に ``requirements.txt`` とされています) に保存しておいて ``pip install -r requirements.txt``
+    のように一括インストールすることができます。
+
+    一方、 pip は easy_install が持っている、複数バージョンの並列インストールには対応していません。
+    最近は virtualenv を使うことが一般的なので、古いバージョンのライブラリを利用する環境と新しい環境を
+    分ければいいからです。
 
 
 インタラクティブシェルを使う
+モジュール
+============
+
+モジュール
+----------
+
+module とは、 php の `require_once` に namespace を組み合わせたようなものです。
+
+同じディレクトリに、 foo.py と bar.py という2つのファイルがあるとしましょう。
+
+foo.py::
+
+    A = 3
+    
+    def add(x):
+        return x + A
+
+bar.py::
+
+    import foo
+
+    print(foo.A)  # => 3
+    print(foo.add(2)) # => 5
+
+bar.py で `import foo` することにより、 foo.py が `foo` モジュールとして
+読み込まれています。 bar.py の中では foo.py の中のグローバルの要素が、
+`foo.X` や `foo.add` のようにして参照できます。
+
+これは、 php の次のようなコードに近いでしょう.
+
+foo.php:
+
+.. code-block:: php
+
+    <?php
+    namespace foo {
+        $A = 3;
+
+        function add($x) {
+            return $A + $x;
+        }
+    }
+
+bar.php:
+
+.. code-block:: php
+
+    <?php
+    require_once 'foo.php';
+
+    echo foo\$A . "\n";
+    echo foo\add(2) . "\n";
+
+2つの重要な違いを覚えておいてください。
+
+* Python のモジュールは特殊な namespace ではなく、ただのオブジェクトです。
+  `import foo` は foo モジュールオブジェクトを `foo` という変数に代入しているだけです。
+* Python でグローバル変数を作っても、それはそのモジュール内でのグローバルであり、
+  他のファイルのグローバル変数と衝突することはありません。他のファイルからは
+  モジュールオブジェクトの属性に見えます。
+
+パッケージ
+-----------
+パッケージとは、他のモジュールを子供に持つことができる **モジュールです。**
+
+通常のモジュールが、モジュール名=ファイル名となるファイルだったのに対して、
+パッケージは通常パッケージ名のディレクトリと、その中の `__init__.py` という
+ファイルが実体になります。
+
+foo/__init__.py::
+
+    FOO = 1
+
+foo/bar.py::
+
+    BAR = 2
+
+baz.py::
+
+    import foo.bar
+    print(foo.FOO) # => 1
+    print(foo.bar.BAR) # => 2
+
+baz.py の `import foo.bar` は、次のような処理をします。
+
+1. `foo/__init__.py` を `foo` モジュールという名前で読み込む。
+2. `foo/bar.py` を `foo.bar` モジュールという名前で読み込む。
+3. `foo` モジュールオブジェクトの `bar` という属性に `bar` オブジェクトを代入する。
+4. `baz.py` ファイルの `foo` という変数に `foo` パッケージを代入する。
+
+ここで重要な注意があります。
+もし `foo/__init__.py` に `bar` という変数を定義した場合、上の手順4番によって
+その変数は上書きされてしまいます。
+
+一方、 `foo/__init__.py` の内容が次の様になっていた場合は結果が異なります。
+
+foo/__init__.py::
+
+    import foo.bar
+    FOO = bar
+    bar = 3
+
+この場合、 baz.py を実行すると次のような順序で実行されます。
+
+1. baz.py の `import foo.bar` により、まず `foo/__init__.py` が `foo` パッケージとして実行される。
+2. `foo/__init__.py` の中の `import foo.bar` が実行される。
+   `foo` パッケージはすでに(読込中であるものの)存在するので、 `foo.bar` というモジュール名で
+   `foo/bar.py` が実行される。
+3. `foo/bar.py` の実行が終わったあと、 `foo` パッケージに `bar` 属性として `foo.bar` モジュールが
+   代入される。
+4. `foo/__init__.py` の `import foo.bar` の実行が完了し、 `foo` という変数に、読込中の `foo`
+   パッケージ自体が代入される。
+5. `FOO = bar` が実行され、 `foo.bar` モジュールが `FOO` という変数にコピーされる。
+6. `bar = 3` が実行される。
+7. baz.py の `import foo.bar` が完了し、 `print(foo.FOO)` が `<module 'foo.bar'...>` と表示する。
+8. `print(foo.bar.BAR)` が実行されるものの、 `foo.bar` は 3 で、 BAR という属性を持たないのでエラーになる。
+
+なので、モジュールとパッケージについて2つの重要な点を覚えておきましょう。
+
+* モジュールは読み込む順番で動作が異なる可能性がある。
+* パッケージ内の変数は、そのパッケージは以下のサブモジュール名と衝突する可能性がある。
+
+php も require_once の実行順で動作が異なる可能性がありますが、普段はその順序にできるだけ依存しないように
+プログラムを書いているでしょう。 Python でも同じように、ファイルのグローバルで副作用のある動作をせず、
+import の順序によって問題を起こさないようにするするべきです。
+
+パッケージ内の変数とサブモジュールとの名前が衝突しそうになった時は、パッケージの外から
+その名前でアクセスしたいのがどちらかを考えましょう。上の例で言えば、 baz.py から `foo.bar`
+を参照した時に変数側を見せたいのであれば、モジュール側は `foo._bar` という名前で
+`foo/_bar.py` に置きましょう。逆にモジュール側をみせて変数側を隠したいのであれば、
+変数名を `_bar` にしましょう。
+
+外に見せたくないオブジェクトの名前を _ で始めるのは Python で一般的な習慣です。
+
+`__name__`
+-----------
+
+foo.py が `python foo.py` として実行された場合も、 `import foo` でインポートされた場合も、
+そのファイルの中身が実行されるという点では同じですが、自動的に定義される `__name__`
+という変数で区別することができます。
+
+スクリプトとして実行されている場合は `__name__` は `'__main__'` になり、
+モジュールとしてインポートされている時はそのモジュール名になります。
+
+`if __name__ == '__main__':` という定型句で、スクリプトとして実行することも
+import することも可能なファイルを作ることができます。
+単にスクリプトを書くだけの場合もこうして置くことで、中の便利な関数を
+使いたくなったときやテストしたくなった時に import することができます。
+
+他の import 文の書き方
+----------------------
+
+as
+~~~
+
+`import foo.bar as fb` と書くと、 `foo` 変数に `foo` パッケージを代入する代わりに、
+`foobar` という変数に `foo.bar` モジュールを代入します。
+import が長い時に、その中の要素にアクセスするために毎回 `foo.bar` と書く代わりに
+`fb` と書くことができます。
+といっても、短すぎてわかりにくい名前は、他のグローバル変数と同じようにやめましょう。
+
+from ... import
+~~~~~~~~~~~~~~~~
+
+`from foo import bar` と書くと、 `bar` という変数に `foo.bar` モジュールが代入されます。
+as と組み合わせて `from foo import bar as foobar` と書くこともできます。
+
+`import foo.bar as bar` と違い、 `from foo import bar` では bar はモジュールである
+必要はありません。 `foo` モジュールの中のクラスや変数など任意の属性を直接インポートできます。
+
+また、服数の要素を一括でインポートする事が出来る点です。次のように書くと、 foo 
+パッケージから fizz, buzz, fizzbuzz の3つをインポートできます。 ::
+
+    from foo import (
+        fizz,
+        buzz,
+        fizzbuzz)
+
+インポートする名前を1つずつ列挙する代わりに、 `from foo import *` のように書くこともできます。
+この場合、 `foo` モジュールが `__all__` という変数名で公開する名前のリストを定義していればそれが、
+そうでなければ `_` で始まる物を除いて全ての名前がインポートされます。
+
+`*` は便利ですが、特に2つ以上使った場合に、そのファイル内で利用している名前がどこから
+インポートしたものか判りにくくなってしまいます。1つだけしか使わない、名前をみたら何か
+ひと目で判るくらい頻繁に利用される場合にだけ使う、など節度を守って使いましょう。
+
+
+相対 import と絶対 import
+--------------------------
+
+Python 2 では `import bar` が foo パッケージや foo パッケージ内のモジュール (`foo.baz` など) で
+実行された場合、 まず `foo.bar` モジュールを探し(相対インポート)、無かったら今度は `bar`
+モジュールを探します(絶対インポート)。
+
+この暗黙の相対インポートがわかりにくいということで、 Python 3 では禁止され、 `import bar` は常に
+`bar` を指すようになりました。 Python 2 でもファイルの先頭に `from __future__ import absolute_import`
+と書くことで常に絶対インポートにすることができます。
+
+その代わりに、明示的な相対 import のための構文が追加されました。 `from X import Y` の X の部分が
+ドット1つで始まっていた場合は現在のパッケージ、ドット2つで始まっていた場合は親パッケージから Y を
+探します。わかりにくいので例を書きます。 `foo.bar` パッケージ内にある `foo.bar.baz` モジュールの
+場合、明示的な相対インポートは次のようになります。 ::
+
+    from . import egg      # from foo.bar import egg
+    from .. import egg     # from foo import egg
+    from .spam import egg  # from foo.bar.spam import egg
+    from ..spam import egg # from foo.spam import egg
+
+明示的な相対インポートは Python 2 でも使えます。他の __future__ の要素 (`division`, `print_function`)
+とともに積極的に利用して、 Python 3 に備えましょう。