Help us understand the problem. What is going on with this article?

あまり基礎から教えてもらうことがない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'

<パッケージ名>.<モジュール名>
でモジュールをインポートする必要があります。
sklearnパッケージの中にtreeパッケージがあって、その下にDecisionTreeClassifierクラスがあって、その中に関数がある。

>>> 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入門
ざっくりん雑記

おわり

hiroyuki_mrp
主にPythonに関する記事を投稿しています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした