Python実践入門 7章 モジュールとパッケージ、名前空間とスコープ
7.1モジュール
Pythonではファイル名がモジュール名になる
code: chap7.py
import base64
def do_something(x):
print(x)
上記のようなファイルを作成したら、import chap7でインポートできる
if __name__ == '__main__': について
よくあるやつ、これは直接このファイルをスクリプトとして実行するか、モジュールとして呼び出すかで挙動を変えたい場合で利用する
code: chap7.py
import sys
def do_something(x):
print(x)
def main():
print(do_something(target))
if __name__ == '__main__':
main()
このmain内をmain外に書いてしまうと、スクリプトとして実行する場合( python3 chap7.py)は問題ないが、モジュールとしてimportした際に、sys.argv部分でエラーが出てしまう
ので、スクリプトとして直接実行される際は、mainがそれ以外(モジュール読み込み)はただ関数たちだけが読み込まれるようにしている
あるモジュールがpython3コマンドに渡されたとき、そのモジュール内の変数__name__の値は文字列__main__になっています。
ちなみにモジュールとして渡した際はモジュール名になっている
code: test
$ python3
>> import chap7
>> chap7.__name__
'chap7'
7.2パッケージ
パッケージはモジュールをまとめる機能
実態はモジュールとかのファイルを集めた、ディレクトリ
パッケージは目印として__init__.pyを配置する(空ファイルでおk)
なくても作れるけど、特殊な名前空間パッケージになるから作ろう
パッケージ内のモジュールのimport
from <パッケージ名> import <モジュール名1>, <モジュール名x>
code: フォルダ構成
$ tree .
b64
├── __init__.py
├── decoder.py
└── encoder.py
$ python3
>> from b64 import encoder,decoder
__init__.pyのもう一つの用法
パッケージの初期化に使える
__init__.pyでパッケージ内のモジュールを読み込んでおくと、呼び出しが楽になる
code: __init__.py
from .encoder import do_something
code: モジュール名.関数名で呼べる
>> import b64
>> b64.do_something('foo')
importのやり方色々
import <パッケージ名>
モジュールのトップレベルオブジェクトが呼べる
呼び出すときに<パッケージ名>.<属性>という呼び方
from <パッケージ名> import <モジュール名1>, <モジュール名x>
importで指定したモジュールだけ呼べる
呼び出すときにパッケージ名.が不要
ワイルドカードを使った一括インポート
from <パッケージ名> import *
asで別名つけてインポート
名前被り防ぐため
from gzip import open as gzip_open みたいな
from <パッケージ名> import <モジュール名> as <別名>
7.3importの仕組み
importパッケージの検索順はローカルディレクトリ->標準ライブラリなど
ローカルにsysというライブラリとかあれば、そっちが優先されてしまうよ
7.4名前空間と変数のスコープ
名前からオブジェクトへのマッピングが名前空間
スコープはまぁ普通のプログラム通り
.をつけずに変数名とかを呼ぶ場合、アクセス可能な名前空間から呼び出す(これがスコープ)
スコープの種類は4つ、ローカルスコープ、グローバルスコープは普通のプログラムと一緒
ちなみに、ローカルスコープ内からグローバルスコープの変数を書き換えたい場合は、globalを指定する
code: global.py
x = 'foo'
def hoge():
global x
x = 'foobar'
print(x) # foobar
ビルトインスコープ
TrueとかFalse, Noneといった組み込みオブジェクトや関数が参照される
エンクロージングスコープ
ローカルとグローバルの中間
入れ子になった関数から1つ外側の参照
クロージャ
関数定義時に、関数外スコープの変数を束縛する関数
Pythonではあまり使うことはないっぽい