Python
Python3
Anaconda

あまり基礎から教えてもらうことがないpythonのimportについて。モジュール?パッケージ?クラス?


はじめに

pythonの基礎として、importの書き方を記載します。


環境

MacOS

anaconda1.8.7

python3.6


こんなこと思ったことありませんか?

pythonを始めてまもない人が、いろんなコードをみて、「書き方が違う」みたいなことを思ったことありませんか?例えば

import matplotlib.pyplot as plt

from matplotlib import pyplot as plt

なんで書き方違うのか?結局どれがどれでどうなってるのか?結局慣例的に記憶することになるからどうでもいいんだけど。となってることもあるんじゃないでしょうか。


モジュールとかパッケージとかライブラリとかってなに?

-関数

def文。関数名()というようにして実行する。一番小さい単位。

-モジュール

複数の関数集めて一つのファイルに記述したもの。

※ファイル名から拡張子.pyを除いたものがモジュール名になる。

-パッケージ

__init__.pyと複数のモジュール(.pyファイル)がディレクトリにまとまったもの。パッケージの中にパッケージを含めることもできます。ディレクトリ名がパッケージ名となり、親.子.モジュールのように.で区切って指定することができます。

__init__.pyにはパッケージの初期化処理を記述します。なければ空でも問題ありません。


Python3.3以降では、__init__.pyを含まないディレクトリもパッケージとしてインポートできるようになった。このようなパッケージを名前空間パッケージ(Namespace packages)という。


-ライブラリ

(どうやら)Pythonには「ライブラリ」という用語の定義はなく、関数・モジュール・パッケージの総称、一般的な意味合いとして使われているらしいです。または、いくつかのパッケージをまとめて一つのライブラリとしてインストールするようにしたものを指すこともあります。


importやってみる

モジュールを使用するにはimportを使います。

-import モジュール名

-import モジュール名 as 略称

例えば以下でmathをimportして型を調べてみます。

>>> import math

>>> print(type(math))
<class 'module'>
>>> print(math)
<module 'math' from '/Users/hoge/anaconda3/lib/python3.6/lib-dynload/math.cpython-36m-darwin.so'>

moduleですね。

ついでにどのファイルを読み込んでいるか見てみます。

>>> print(math)

<module 'math' from '/Users/hoge/anaconda3/lib/python3.6/lib-dynload/math.cpython-36m-darwin.so'>

次に

-<モジュール名>.<関数名>

-<モジュール名>.<変数名>

のようにすることでモジュール内で定義された関数やグローバル変数などを使用できます。

>>> print(math.radians(180))

3.141592653589793
>>> print(type(math.radians))
<class 'builtin_function_or_method'>
>>> print(math.e)
2.718281828459045
>>> print(type(math.e))
<class 'float'>

※math.eは自然対数の底(ネイピア数)です。

上の関数の呼び出しを行うたびに毎回入力するのは面倒なので

そんなときはfromを使ってimportを行います

-from モジュール名 import オブジェクト(クラス名もしくは関数名もしくは変数名)

>>> from math import pi, e

>>> print(e)
2.718281828459045
>>> print(pi)
3.141592653589793

以下のようにワイルドカードを使うとすべてのオブジェクトをインポートすることができます。

※ただしPEP8ではこのimportは名前空間の存在が不明瞭になるので推奨はされていないです。

from math import *


パッケージからモジュールやオブジェクトをimport

以下のようにimport sklearnとしても、配下のモジュールを使うことはできません。AttributeErrorとなります。

>>> import sklearn

>>> print(sklearn)
<module 'sklearn' from '/Users/hoge/anaconda3/lib/python3.6/site-packages/sklearn/__init__.py'>

>>> print(sklearn.tree)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'sklearn' has no attribute 'tree'

<パッケージ名>.<モジュール名>

でモジュールをインポートする必要があります。

>>> import sklearn.tree #from sklearn import treeでもいい

>>> print(sklearn.tree)
<module 'sklearn.tree' from '/Users/hoge/anaconda3/lib/python3.6/site-packages/sklearn/tree/__init__.py'>

>>> print(sklearn.tree.DecisionTreeClassifier)
<class 'sklearn.tree.tree.DecisionTreeClassifier'>

オブジェクトを指定してimportする場合は

from sklearn.tree import DecisionTreeClassifier

dir()を使うことで、配下にあるものを確認することができます。

>>> dir(sklearn.tree)

['DecisionTreeClassifier', 'DecisionTreeRegressor', 'ExtraTreeClassifier', 'ExtraTreeRegressor', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_criterion', '_splitter', '_tree', '_utils', 'export', 'export_graphviz', 'tree']


補足:モジュールの作成

.pyの拡張子をもつファイルは、pythonのモジュールとして他のモジュールから利用することができます。

以下に簡単なモジュールを作ってみます。


testmodule.py

class Testclass:

def testkansu(self, str):
print(str)

if __name__ == '__main__':
test = Testclass()
test.testkansu("test_dayo")


実行します。

$ python testmodule.py

test_dayo

他のモジュールから、importで呼び出して、moduleからclass生成をします。

※拡張子の.pyは不要

※モジュールとしてimportで呼び出した場合は__main__以下は実行されません。

>>> import testmodule

>>> a = testmodule.Testclass()
>>> a.testkansu("test-dayo")
test-dayo

fromを使ってオブジェクトを呼び出してみます

>>> from testmodule import Testclass 

>>> a = Testclass()
>>> a.testkansu("test-dayo")
test-dayo

>>> dir(Testclass)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'testkansu']


補足の補足

ファイル内にあった__main__とかの兄弟について。

パッケージ名(__package__)

__package__ は、現在のパッケージ名を示します。

ファイル名(__file__)
__file__ は、現在のファイル名を示します。

モジュール名(__name__)
__name__ は、現在のモジュール名を示します。
メインモジュールの場合は __main__ という名前が設定されます。

ビルトインモジュール(__builtin__)
__builtin__ は、open() などのビルトインオブジェクトを包含するモジュールを示します。


importに関するエラー

ModuleNotFoundError

モジュールが見つからない時のエラー。

名前が間違っているか、importの対象ディレクトリのパスの指定が間違ってい場合、またモジュールではなくオブジェクトなどをimportしようとした場合にもModuleNotFoundErrorとなります。オブジェクトをインポートする場合はfromを使います。

AttributeError

importしたモジュールに指定した属性がない時にでるエラー。

名前が

間違っているか、想定と異なるファイルがimportされている可能性がある。


参考

Pythonのimportについてまとめる

Macでtreeコマンド

とほほのWWW入門


おわり