Python♪パッケージは、本を目で追うだけではわかりにくい。JuneホームPython♪の学習とホームページ作成のブログPython♪パッケージは、本を目で追うだけではわかりにくい。2018.09.04パッケージって、プログラムの初心者はあまり使わない(?)ですし、練習でコードを書くのにもフォルダを複数作る必要があり、面倒です。その割に、本を目で追うだけでは、わかったつもりになってしまう内容が多いです。この記事では、初心者が勘違いしたり、見落としそうな内容を整理し、ピックアップしたいと思います。パッケージの理解には、自分でもコードを入力し実行してみることをお勧めします。一度、importしたモジュールはPythonのインタプリタを、終了させなければimportしたままになるため、コードを検証する場合には、再起動する必要がありますので注意してください。名前空間パッケージの利点1.パッケージとはパッケージを使うと、関係のある複数のモジュールをディレクトリ(フォルダ)にまとめ、整理することができます。通常はモジュールを使用するときにはモジュールが入ったディレクトリにPATHが通ってなければなりません。パッケージの機能を使うと、importするときに、ディレクトリ(フォルダ)名と半角ピリオド「.」を用いて、モジュールの位置を指定することができるようになります。例として、以下の図ようなフォルダ(ディレクトリ)構成のパッケージがあったとします。この例ではディレクトリpython_codeにはPATHが通っているという設定ですので、モジュールmain_mod.pyはフィル名を指定して実行することは可能です。ディレクトリaaa1やbbb1にはPATHが通っていませんので、パッケージの機能を使わなければ、その中にあるモジュールbbb1_mod1.pyは指定することができません。この例ではディレクトリaaa1とbbb1には__init__.pyを入れ、パッケージであることを明示しています。bbb1)を使ってimport文を記述することができます。aaa1.bbb1.bbb1_mod1」という記述が可能になります。__init__.pyはコードを全く記述しない空のファイルでもかまいませんが、コードを記述することもできます。※実はPytyon3.3からは、名前空間パッケージ(ネームスペースパッケージ)を用いることにより、__init__.pyがなくても同様のことができるようになりました。__init__.pyがなくてもエラーにはなりません。通常のパッケージ(レギュラーパッケージ)には__init__.pyが必要ですので、必要なものとして読み進めてください。通常のパッケージと名前空間パッケージの違いは、「7.通常のパッケージと名前空間パッケージ」で簡単に述べます。[a001]この記事のTopに戻る2.パッケージからimportするための2つの書式パッケージ内のモジュールをインポートする書式には2種類あります。具体的な例でインポートの仕方を説明します。○○.△△.□□」という書式です。最後の□□はモジュール(あるいはパッケージ)にする必要があり、クラス、関数、変数にはできません。すると、必然的にその前の○○や△△は、パッケージになります。この書式で読み込んだモジュールを使用するときは、○○.△△.□□としなければなりません。○○や△△は省略することはできません。コード01は、モジュールbbb1_mod1.pyの関数bbb1_def1を、main_mod.pyからimportし、実行したコードです。xxx.関数名()」といった書式で実行しています。実行例3のように、aaa1.bbb1.を省略することはできません。aaa1.bbb1.bbb1_mod1xxx.bbb1_def1()#関数の実行例3(エラー)#aaa1.bbb1.を省略することはできません。PATHが通っていないディレクトリの扱いディレクトリに__init__.pyを入れることにより、どこからでも呼び出せるようになるわけではありません。bbb1.bbb1_mod1」としていますが、ディレクトリbbb1が入っているディレクトリaaa1にはPATHが通っていませんので、aaa1.を省略することはできません。以下の例はエラーになります。#コード02(エラー)#bbb1が入っているaaa1にPATHが通っていない。○○.△△.□□の書式は、□□をパッケージやモジュールにできるといいましたが、□□をパッケージとした場合、ディレクトリ□□の中のモジュールにはアクセスできません。パッケージをimportした場合は、ディレクトリ□□の中の__init__.pyに、必要なモジュールをimportするコードを記述するといった使い方をしなければ、使い方が限定されると思われます。コード03は、パッケージのbbb1をインポートした例ですが、実行例1、実行例2のようにbbb1の中のモジュールを呼び出そうとするとエラーになります。‘module’>が出力されますので、aaa1.bbb1がインポートされていないわけではありません。aaa1.bbb1#関数の実行例1(エラー)#bbb1の中のモジュールはimportされていない。aaa1.bbb1.bbb1_mod1.bbb1_def1()#関数の実行例2(エラー)#bbb1の中のモジュールはimportされていない。'module'>が出力される。□□」では、importの後の□□の部分は、△△.□□のようにドットが入る書式にはできません。△△.□□」とは書き換えられません。(コード04のインポート例2を参照)なお、□□は、書式1と異なり、パッケージ、モジュール、クラス、関数、変数のどれでもかまいません。モジュールを実行するときは、importの後の□□を使います。○○.△△.□□とすると、エラーになります。bbb1_mod1#インポート例2(エラー)#importより後は「.」が入った書式にできない。bbb1.bbb1_mod1#関数の実行例1bbb1_mod1.bbb1_def1()#関数の実行例2(エラー)#fromのあとのaaa1.bbb1は記述できない。aaa1.bbb1.bbb1_mod1.bbb1_def1()[a002_04]この記事のTopに戻る3.__init__.pyが実行されるタイミングモジュールはimportしたときに一度だけ、モジュール内のコードを実行します。その性質を使って、__init__.pyが、どのタイミングでimportされるのかを確認します。フォルダ構成と各モジュールのコードは以下のようになっています。結果から言うと、import文の中で、その__init__.pyが入ったディレクトリの名称が使われるときに実行されます。bbb1の__init__.pyが実行されます。出力05では、__init__.pyのインポートはコード05の1行目のprint文よりも後に実行されています。コードが実行される前にまとめて__init__.pyが処理されるわけではありません。bbb1_def1」の赤字の部分により、モジュールbbb1_mod1のコードが実行されています。コード05の4行目は、モジュールbbb1_mod1ではなく、関数のbbb1_def1をimportする命令文なのですが、モジュールbbb1_mod1のコードが実行されています。bbb1_def1は、モジュールではなく関数ですので、インポートされるときに関数の中のコードは実行されません。その他にも、メインモジュールであるmain_mod.pyの「__name__」が「__main__」になっているのに対して、モジュールbbb1_mod1の「__name__」が「aaa1.bbb1.bbb1_mod1」になっている点が注目ポイントです。モジュールの「__name__」は、メインモジュールとして実行したときには「__main__」となり、import文でインポートした時には「モジュール名」となります。パッケージを用いて読み込んだ場合には、モジュール名「bbb1_mod1」だけではなく、モジュールの位置がわかるように「aaa1.bbb1.bbb1_mod1」となっています。[a003]この記事のTopに戻る4.絶対importと相対importimportによるモジュールの位置の指定には、絶対importと相対importがあります。今までの具体例は、全て絶対importです。bbb1_def1」のように、PATHが通っているディレクトリ内のパッケージaaa1から始まる記述になっています。「カレントディレクトリ」からの相対位置によってモジュールの位置を示すのが相対importです。相対importでは、以下の様にピリオド「.」を用いて相対位置を表現します。下の図のようなフォルダ(ディレクトリ)構成で、図の右に示すようなコードが記述されているとします。この場合、モジュールbbb1_mod2からモジュールbbb1_mod2や関数bbb1_def1をimportするときは、コード06のようになります。呼び出し元のモジュールbbb1_mod2が存在するディレクトリ(bbb1)がカレントディレクトリになります。bbb1_mod1」の「.」は、絶対importでは「aaa1.bbb1」に相当します。○○.△△.□□」では使用できず、エラーとなります。.bbb1_mod1次に、モジュールbbb1_mod2からモジュールaaa1_mod1や関数aaa1_def1をimportする例をコード07の示します。「..」は呼び出し元のモジュールbbb1_mod2のカレントディレクトリ(bbb1)の親のディレクトリ(aaa1)を示します。aaa1_mod1」の「..」は絶対importの「aaa1」に相当します。以下、main_mod.py(コード08a)、bbb1_mod2.py(コード08b)のコードと、main_mod.pyの実行結果を出力08に示します。どの様な順番で実行されているのかが、出力08を見ればわかると思います。min_mod.pyの出力には「■」、bbb1_mod2.pyの出力には「□」を出力の頭につけました。メインモジュールには相対importは使えないメインモジュール(main_mod.py)に下記のような相対importは使用できません。相対importを使うと、出力09のようなエラーが発生します。上の出力08の13行目を見るとわかりますが、モジュールをメインモジュールとして使う場合には、変数__name__には’__main__’という文字列が代入されます。相対importでは、この’__main__’という文字列がカレントディレクトリの位置を示す文字列として認識されます。’__main__’は、モジュールの位置を示す名称とは扱えないので、「’__main__’がパッケージではない」というエラーが発生したのです。10行目のように、import文によりインポートされたモジュールは、変数__name__に、カレントディレクトリの位置を示す文字列が代入されるので、相対importを使うことができます。#コード09(エラー)#メインモジュール(main_mod.py)では相対importは使用できない。*」のような書式で「*(アスタリスク)」を使って、ディレクトリ内のモジュールを一度にインポートしようとしても、複数のモジュールを読み込むための準備をしなければ、なにもimportできません。それなりの準備をすれば、複数のモジュールを一度にインポートできますが、不特定多数のモジュールがインポートされてしまうこの方法は、推奨されていませんので、極力避けるようにしてください。*」だけでは何もインポートできない下のようなディレクトリ(フォルダ)構成のパッケージがあったとします。main_mod.pyのコードがコード11のように、単純にモジュールbbb1_mod2を読み込むだけのコードを実行すると、出力11のように出力され、モジュールbbb1_mod2がインポートされていることがわかります。aaa1.bbb1.bbb1_mod2次に、importの後を「*」にしてみます。bbb1_mod2は、どちらもインポートされていないことがわかります。*」を使って「モジュール」を読み込むのはこれだけではできません。*」により読み込み可能です。*」とすれば、モジュールbbb1_mod1の中の関数「bbb1_def1()」を、関数名だけで呼び出せるようになります。*」により、モジュールを読み込むことができるのでしょうか。以下、2つの使い方をご紹介します。*」でインポートすると、モジュールを呼び出すときに○○.△△の部分を省略できます。コード13では、5行目の関数の実行部分で、「aaa1.bbb1.bbb1_mod2.bbb1_def2」とする必要があり、エラーになります。*」とすると、「aaa1.bbb1.」は不要となり、「bbb1_mod2.bbb1_def2()」で、関数を実行することができました。*」を用いて、複数のモジュールを読み込む方法として、__init__.pyの中に「__all__=読み込みたいモジュール名のリスト」を書き込む方法があります。コード15a(main_mod.py)と、コード15b(ディレクトリbbb1の中の__init__.py)を見てください。*」とすることで、複数のモジュールをインポートすることができました。aaa1.bbb1」だけでは、「__all__=モジュールのリスト」で指定したモジュールはインポートされません。'bbb1_mod2']#出力16ディレクトリaaa1の中の__init__.pyディレクトリbbb1の中の__init__.py[a005_03]この記事のTopに戻る6.__init__.pyの中でimportする方法__init__.pyの中で、複数のモジュールをimportする方法もあります。この方法であれば、相対importや絶対importにより、様々な場所のモジュールをインポートすることが可能です。この方法は、「__all__」を使う方法よりも、更に不特定多数のモジュールがインポートされてしまいますので、極力、使用を避けたい方法です。下のようなディレクトリ構成のパッケージを想定します。この中で、ディレクトリbbb1の中の__init__.pyに、import文を記述します。bbb1_mod2をimportするためのimport文が記述されています。aaa1.bbb1」とし、パッケージbbb1をインポートします。この方法でimportしたモジュールは、モジュール名だけでは実行できず、「aaa1.bbb1.bbb1_mod2.bbb1_def2()」「aaa1.aaa1_mod1.aaa1_def1()」といった書式で、関数を実行します。*」を使用する方法ディレクトリの構成は先ほどの例と同じです。メインモジュールであるmain_modのコードのみ、記述内容を変えます。bbb1_mod2をimportするためのimport文が記述されています。この方法でimportしたモジュールは、モジュール名だけで実行できでき、モジュール名の前にパッケージ名を加えるとエラーになります。aaa1.aaa1_mod1モジュールbbb1_mod2の関数bbb1_def2モジュールaaa1_mod1の関数aaa1_def1[a006_02]この記事のTopに戻る7.通常のパッケージと名前空間パッケージ通常のパッケージ(レギュラーパッケージ)と名前空間パッケージ(ネームスペースパッケージ)の実用的な部分での違いを簡単に説明します。明快な通常のパッケージを利用することをお勧めします。__init__.pyの中に「__all__=[モジュールのリスト]」という書式で一度にimportしたいモジュールを列挙することができる。__init__.pyの中にimport文を記述することができる。__init__.pyが入っていれば、パッケージであることが判別できる。__init__.pyを省略できる。PATHが通っているところに、同じ名前のディレクトリが存在した場合でも、それぞれの同名のディレクトリの中にあるモジュールを指定することができる。これは、メリットでもあり、デメリットでもある。(通常のパッケージではエラーになるため、ディレクトリ名の重複をさけることができる。10.6.数学」に出てくるrandomモジュールの関数を整理してみました。randomモジュールには、他にも、便利な関数が多くありますが、まずは、この記事に出てくる関数から覚えてはいかがで...PythonPython♪本当は変数には参照先のアドレス(id)しか入っていない変数aに整数3を代入するとは、aという名前の箱に整数3を入れるようなイメージですが、実際にはそうではありません。整数オブジェクト3が別のところに独立して生成され、変数aには整数オブジェクトの保存先のアドレス(id)のみが記述されます。この...PythonPython♪私が購入したPythonの書籍のレビューPythonの勉強で実際に私が購入した書籍を紹介したいと思います。たくさんの書籍の紹介を見ていると、調べれば調べるほど何がよいのかわからなくなってしまいます。私の選択がBestであるとは思っていませんが、購入に至った動機や感想などが少しで...PythonPython♪リストの内包表記が苦手な人は図で感覚をつかもう慣れないとリストの内包表記って頭が変になりませんか。そんな場合は、図で感覚をつかみましょう。リストの内包表記は、for文やif文を使ったリストの作成がたった1行で書けてしまう便利な表記です。うまう使いこなせばすっきりした見やすいコ...PythonPython♪基本:コメントアウトと、インデントやエスケープシーケンスこの記事では、「コメントアウト」「複数行のコメントアウトもどき」「エスケープシーケンス」の説明をします。メインはコメントアウトの説明ですが、ひょっこり、「エスケープシーケンス」の説明が入っています。どのように、「エスケープシーケンス」が「...PythonPyrhon♪リストのインデックス指定とスライスの例題ゆうちゃんとのPythonの勉強もリストのスライスを覚えるところまで進みました。スライスはリスト操作において大変便利な機能ですのでしっかりと覚えましょう。Studioが遅いときの対策2020.01.11Kotlin♪環境設定「HAXMがインストールされていません」2020.01.052020.01.08Python♪FEM:部材座標系の要素剛性マトリクス2020.01.04Kotlin♪スマホアプリの言語は、Kotlin、Java、C#、Dart?2020.01.012020.01.13スポンサーリンクスポンサーリンク。