見出し画像

【Python】悪いことはいわない。コードを分けて、見やすくしよう。

みなさんは長いコードを書いていると、エラーが起きた時大変になったことはないでしょうか?

どの文が原因でエラーが起きているの…🥺?

と困った経験はありませんか?
実はPythonにはそんなみなさんのために、

「コードを分割しても読んでくれる仕組み」

があるのです。それでは、はじめます。

急ぎの方は動画にて、コードの分割だけについて2〜3分で知ることができます↓

モジュールとは?

そもそも、Pythonのコードを書くとき、基本.pyファイルで保存して作っていますよね?
.pyファイルを

「モジュール」

とPythonでは呼んでいます。

モジュールは

いくつも作れる

のですが、
同じフォルダにモジュールを置いて、分けても

認識しません。

では、どうすれば良いのでしょうか?

モジュールの関数を呼び出すにはどうするかというと、

①最初の1行目にimport [モジュール名]※.pyは除いておく!!
②モジュールの名前.関数の名前([引数])

と順番にコードを書いていきます。これで、コードの分割が可能です。

では、

たとえば、同じフォルダがあったとして、以下のコード、クラスがあったとします。
test2.pyのコード↓

class A:
   def __init__(self):
       print('A Loaded')

test.pyのコード↓

import test2
k=test2.A()

test.pyで実行してみると、

実行結果

A Loaded

無事呼ばれていることがわかります。

コードの分割によって可読性はよくなる。でもウィンドウが増える結果となる。

デメリットは、デバッグの状態によっては、

「ウィンドウの数が増える」

ことです。ですが、もし

「関数の特徴だけ」

を知りたいだけなのなら、

「docstringの形式でコメントを残す」

ことによって、VisualStudioCodeなどで、関数を候補で選ぶことで、関数の説明を表示することができます。

えっ!?docstringって何ぞや🤯…?

と思われた方は、

「すでに作った関数の使い方を忘れないうちにメモしとこ〜♪」のところ

をチェックしてみてください。

次のNoteで説明しています↓

そもそもデバッグってできるん…🥺?

では、コードが分割されていてもデバッグってできるのか気になりますよね?ここでは、VisualStudioCodeを使って、実際に検証してみました。実行するコードではなく、あらかじめimport構文で紐付けを行ったモジュールでブレークポイント(BreakPoint)検証しています。

実行したモジュール( .py )にimport構文でひもづけたモジュール( .py )にブレークポイント(BreakPoint)をつけて検証。実際にデバッグ。ちゃんと止まっているので、ちゃんとデバッグの検証が行える🤔✨
実際のVisualStudioCodeの画面。実行したモジュール( .py )だけではなく、import構文で関連付けを行ったモジュール( .py )でもちゃんとデバッグできていることがわかる🧐✨

デバッグしたときに、関連付けを行ったモジュールでもきちんと

ブレークポイントに止まっている

ことがわかります。コードが分割されてもデバッグをされているのはめっちゃ便利ですよね!!

いくつかのモジュールは束ねておける!

また、Pythonでは

「いくつかのモジュール」を束ねる

こともできます。いくつかのモジュールをフォルダにまとめたものを

「パッケージ」

と呼びます。
パッケージを呼び出すとき、
まず、フォルダの中に

__init__.py

を空でも良いので、作っておきましょう。

さて、パッケージを実行したいモジュールにimportで取り入れてみましょう。

書き方は

import [パッケージ名].[モジュール名]・・・①

でもOKですし、

from [パッケージ名].[モジュール名] import [クラス名]・・・②

でもOKです。(ただし、②に関しては特定のクラスを使いたいときに使います。)

モジュール名の前にドット「.」をつかって、

「パッケージ名」

を添えましょう。

たとえば、moduleパッケージのtest2モジュールにあるAクラスを取り入れたかったとします。

test2.py(moduleフォルダ)

class A:
   def __init__(self):
       print('A Loaded')

があるとすると、

test.py

from module.test2 import A
k=A()

を取り入れることによって、

実行結果

A Loaded

というふうに

from [パッケージ名].[モジュール名] import [クラス名]

でも無事アクセスできていることがわかります。

ただし、

「importで取り入れたクラス名しか呼び出せません」

ので、複数のクラスを呼び出したい場合は注意が必要です。

応用編①:import構文の理解をさらに深めよう

では、コードの分割、モジュール、パッケージの作り方を説明したところで、さらにimport構文の理解を深めていきましょう!!

import [モジュール名] as [任意の名前]で別の名前をつけることができる

ちなみに、

import [モジュール名] as [任意の名前]

をつかうと、モジュールを別の名前で使うことが可能です。さきほど

の構文でわかりやすくするために、

「任意の名前」

と書きましたが、この「任意の名前」のことを

「エイリアス」

と呼びます。

たとえば、CSVファイルなどを使ってデータベース化してくれるライブラリ、pandasを例にあげるなら、

import pandas as pd (「これから、pandasをpdの名前で書きます。」という意味です。)

と書かれてあることが多いですよね。pandasをpdで書けるので、タイピングのミスをつなげることができます。
また、

import pandas as pd

は定型文として使われていることが多いです🤔
Qiita.comなどのサイトで調べていると、よく出てくるので、覚えておくと、コードを読むときに戸惑わないかもしれません。実際、pandas公式サイトでもこの

import pandas as pd

の書き方は推奨されているようで、「10 minutes to pandas」の見出しのところに、

Customarily, we import as follows:(慣例では、次の通りにインポートします:)

In [2]:import pandas as pd

pandas公式サイトの「10 minutes to pandas」より

と書かれています。

pandasに限らず、定型文としては、

import seaborn as sns
import numpy as np

などいろいろあるので、もし興味がある場合はいろいろと調べてみてください。

import構文を使ってモジュールからクラスだけを呼び出すには…?

なお、さきほど挙げた

import [モジュール名]
import [モジュール名] as [任意の名前(エイリアス)]

のほかに

from [モジュール名] import [クラス名]

の書き方もあります。
こちらでは、1つのクラスだけしか取り入れることができませんが、

モジュール名を省略して入れる

ことができます。
それでは例をあげながら説明していきましょう。

from test2 import A
k=A()

のようにfromで指定したモジュールを省略しても、
出力結果

A Loaded

で問題なく、出力されました。
そのかわり、

Aのクラスしか使用できない

ことに注意してください。
そういえば、Selenium(ブラウザのテストやスクレイピングに使われるライブラリの一つ)について調べてみると、

from selenium import webdriver

と書かれていますよね。さきほど、

from [モジュール名] import [クラス名]

と説明しましたが、この

from selenium import webdriver

の場合、

from [パッケージ名] import [モジュール名]

でも使えます。

あれ…パッケージって何…?

簡単に説明すると、モジュールの集まりです。

モジュール( .py )ファイルの集まりがパッケージである。
要するに、パッケージ=モジュール+モジュール…です。つまり、パッケージはモジュールの集合体なのです🧐✨

つまり、

「モジュールを整理したい」

ときに使えるのです!!個人でPythonのプログラムを組むと、小規模で収まるので、別に覚えなくてもいいのですが…🤔🤔

ががががっ!!

Seleniumとかpandasなどのライブラリを理解するには、

パッケージとモジュールの区別

はしておいたほうがいいと思います。なぜなら、seleniumなどのライブラリを使うときには

「パッケージだらけのライブラリ」

がほとんどなので、ライブラリを使いこなすためには、

「パッケージとモジュールの区別」

はしっかりとしておいたほうが良いと思います。もちろん、クラスもメソッドもですっ!!

応用編②:import構文の達人になってみよ〜〜〜🥳

これまで多くのimport構文の使い方を説明してきましたが、たくさんのバリエーションに驚かれた方も少なくないのかもしれません。
では、どうやってパッケージからモジュールにたどり着けばよいのでしょうか?それは、「.」演算子を使うことです。「.」演算子はパッケージとモジュールで出てきた演算子ですが、

パッケージの中の中の…

を指定したいときに使えます。わかりにくいと思うので、図で示すと、

「.」の演算子を用いることによって、パッケージ▶モジュール▶クラス、メソッドの順に入ります。
「.」を入れればいれるほど、パッケージ
の中へドンドン入ることができるのです!!

上の図のように

奥へ奥への円の内へと入り込む感じ

という感覚で、コードを書いていけば、すればよいのかもしれません。🤔

from [パッケージ名] import [モジュール名]

を「.」演算子の特性を応用すれば、

from [パッケージ名].[パッケージ名]… import [モジュール名]

というふうに中に入り込めます。

個人的には、

  • from 「外」 import 「内」

  • import 「外」.「外の内」. …

  • import A as B はAに対し別名をつけたいときに使う

というふうに理解すれば、スッキリするのかもしれません。

最初は混乱するのかもしれません。ですが、実際にこういう考え方を頭に入れておくと、

  • Seleniumなどの大規模ライブラリの構造への理解

  • すっきりしたコードを書く

のに役立ちます。

selenium公式サイトのドキュメント。「.」演算子が使われていることがわかる。大部分がパッケージだが、「.」を使えば使うほど、パッケージの中に入れるようになっている。
seleniumのPython版
公式サイトのドキュメント(英語)。
関数の用語を見てみると、ドット「.」の
演算子が大量に使われていることがわかる🤔

一般的にimport構文の説明は

from [パッケージ名].[モジュール名] import [クラス名]

などで書かれていることが多いですが、実際には、上のSelenium公式サイト
などから見てわかるように、「.」の演算子は

パッケージの中に入り込め〜る

ことを意識することによって、import構文に対する理解が深まり、

なんで、seleniumを使うときだけ、こんなに「.」を使うことが多いんだろう…🥺

という違和感は少なくとも拭えると思います。

まとめ

モジュールは

「Pythonのコードが書かれてあるファイル」

です。

パッケージは

「モジュールをまとめたフォルダ」

です。

①import [モジュール名]
②from [モジュール名] import [クラス名]

と書くことでファイルを分割してもプログラムが動いてくれます。また、

パッケージとして認識させるには、モジュール名の前に

「パッケージ名」

を書き、

パッケージであるフォルダの中に

__init__.py

を忘れないようにしましょう。

呼び出すときには、

①はモジュール名は必要
②はモジュール名をはぶくこと

ができることを忘れないようにしましょう。また、
「.」演算子を応用することによって、

パッケージの中から中へ

と入りこむことができます!!それではよきPythonライフをお楽しみくださいませ〜😌

参考文献

この記事が気に入ったらサポートをしてみませんか?