Pythonとは?特徴と学ぶ理由
海外ではメジャー、しかし国内ではマイナーというものがITの世界では結構あります。とりわけ日本の場合旧来のものを由とする風潮がユーザ側に多いが為に、開発側まで世界に遅れてから採用する傾向が昔からあります。そういったものの一つがPython言語。
このPython自体すでにVersion3.x系にまで至っており、1990年生まれの歴史ある言語。サーバサイドからクライアントアプリまで、様々な領域で利用されています。今回は学習に重点を置いてまとめてみようと思います。
概要
元々はスクリプト言語の1つとして誕生し、サーバサイドつまりPHPやNode.jsのようにサーバーアプリケーション(ウェブフレームワークを使ったウェブアプリケーションも)を作ることが可能であり、スクリプト言語であるため、ローカル環境でも実行が可能。多種多様なライブラリが用意されていて、導入する事で簡単に機能を扱うことができる点はNode.jsを使ってる人からすると馴染みがあります。
Version2.x系がこれまでの主流でしたが(2020年サポート終了予定)、現在は並行してVersion3.x系が進んでおり、両者に完全な互換性はないため、これから学ぶのであれば3.x系がオススメ。ただし、多種多様な資料がウェブにはあるものの、2.x系なのか?3.x系でも通じるものなのか?見極める必要があるため、ここが現在学習の障壁になってる。
日本では「機械学習」であったり、「データ解析」の観点から注目されてる節があるものの、元々それを専門とする言語ではなく、非常に優れたライブラリがあるため、注目されてる(但し、それぞれの領域に関する知識が別途要求されるので、誰でも容易に実現できるわけではない)
また、国内ではRaspberry PiのようなワンボードコンピュータのIoTで非常によく利用されている。これも各種センサー用のPythonライブラリが非常に豊富であるのが理由の1つ。
言語の特徴として非常にシンプルな構文で、誰が書いても同じような構文で実現できるように設計されているという。他の言語のように利用者の能力によって差が出にくい。しかし、スクリプト言語であるため、実行速度は遅く、高速化を目指す場合には、やはり書き方であったり、アルゴリズムで乗り越える必要があるみたい(この辺りはGoogle Apps Scriptにも言えることですね)。
開発環境の準備
macOSやLinuxの場合、OS標準でPythonが入っていたりします。Windowsの場合はゼロから環境を構築する必要性があります。しかし、前者の場合でもOS標準よりもゼロから構築したほうが良いと思います。理由はバージョンが古い、OSのバージョンアップに伴って巻き込まれるなどなど。
ダウンロードとインストール
本家ウェブサイトからインストーラを手に入れて、実行します。インストールする事で、PythonだけでなくPython Launcherと呼ばれるpyファイルを直接実行することのできるランチャーアプリもインストールされます。通常はターミナルからコマンドで実行するものですが、ランチャーを使ってバージョンを切り替えながらの実行も可能です。
Windowsユーザの場合、
- インストール時に「Add Python 3.8 to PATH」にチェックを入れておくことで、パスが環境変数に登録されるので、忘れずに入れておきましょう。
- 32bit版と64bit版の2つが用意されているので、使用してるOSのbitを考慮して選択する必要があります。標準だと32bit版がダウンロードされる。64bit版は場所がわかりにくいので注意。
- インストール後のDisable Path length limitの項目が出ます。PATHが260文字を超える場合、Windows10ではそれを解除できるものですが、通常は実行しなくても良いです。
図:インストール自体はとっても簡単
図:WindowsユーザはPATHの追加をチェックしておこう
バージョンの確認と実行
macOSの場合、ターミナルからpython3 --versionを実行するだけでバージョン確認が可能です。また、pyファイルの実行もpython3 test.pyといった具合に実行するだけ。非常に簡単です。PATHの確認は、which python3で確認可能です。デフォルトでは、/usr/local/bin/python3となります。
Windowsの場合、コマンドプロンプトからpython --versionでバージョン確認が可能です。また、pyファイルの実行もpython test.pyといった具合に実行するだけ。PATHの確認は、環境変数を見るとわかります。デフォルトでは、C:\Users\ユーザ名\AppData\Local\Programs\Python\Python38\Scripts\になります。
図:環境変数にPATHは記述されている(Win)
ライブラリの追加
Node.jsでいう所のnpmのようなものとして、Python3.xにはpip3があります。dateutilというライブラリをインストールするのであるならば、pip3 install python-dateutilでインストールが可能です。Node.jsのようにプロジェクト毎にインストールされるわけではないので注意。uninstallでライブラリを除外できます。ライブラリのアップグレードは、pip3 install --upgradeという具合に、オプションを付け加えます。
※python2.x系が入っていない環境の場合はpipで、3.x系も同居してる場合には、pip3を使うようになります。
使用する場合には、pyファイルをテキストエディタで用意して、Node.jsのようにライブラリを呼び出す構文を書く必要があります。例えば、数年後の日付を求めるのであれば以下のような構文を記述します(relativedeltaというクラスを呼び出します)
1 2 3 4 5 6 7 8 9 |
#ライブラリのロード from datetime import date from dateutil.relativedelta import relativedelta #今日の日付 today = date.today() #4年後の日付 print(today + relativedelta(years=4)) |
図:pip3でライブラリをインストール
Python自体をアップグレードする場合
Python自体のアップグレードは、新規インストール時と同じようにインストーラを実行して上書きインストールすればOKです。ですが、追加でインストールしたライブラリ類はゼロからインストールし直しが必要であるので、以下の手順で再インストールを行います。
- pip3 freeze > requirements.txtでインストール済みライブラリ一覧をエクスポートしておく
- Pythonをバージョンアップさせる
- pip3 install -r requirements.txtにて、エクスポートした一覧からライブラリを一括インストールする
プログラミング言語の特徴
プログラミング言語にはそれぞれ特徴がありますが、Pythonは非常にシンプルで、逆に他の言語で慣れている人にとっては、とっつきにくい部分があるかもしれません。
変数の特徴
Pythonの変数はvarやletのような定義が存在しません。いきなり変数名を書いて代入するだけ。定数(Const)のようなものも存在しない。但し、JavaScript同様、代入した値によって暗黙的に型が決まるので、JavaScriptの変数の扱いがよりシンプルになったものと思えばOKなのかなぁと。また、変数だけを定義しておいて、後で利用するとエラーになるので、定義時に代入が必要になります。
また、現在その変数の型を調べたい場合には、type(変数名)といったように、typeで調べることが可能です。intなら数値、strなら文字列、dictならdictionary型、関数ならfunction型といった具合に答えが返ってきます。
インデント
殆どの言語では、インデントはソースコードを読みやすくするための文字の字下げを意味します。if文などで同じラインにコードを並べてしまうと、すごく読みにくい。なので、if{}の括弧内では、1段頭の文字を下げて上げる。しかし、Pythonではif文などに括弧がありません。
括弧の代わりにインデントを使うことで、そのif文の中である事を意味する(ブロック内である)ので、コードのみやすさのためにあるわけではないという点がちょっととっつきにくい点だと思います。このインデントですが、およそ1インデント4文字が目安とされています(コーディング規約)。
厄介なのは、「インデントする文字数は一致させておく必要がある」ということです。1行目は2文字、2行目は4文字なんて形でインデントをしてしまうと、エラーが出てしまいます。自分は普通にTABキーでインデントさせているのでこういった事態をさけらやすいですね。
1 2 3 4 5 6 7 8 9 10 |
#IF文でのインデントの一例 a = 12 b = 12 #IF文で比較する if a == b: print("同じ値みたい") print("よかったね") else: print("値が一致しません") |
図:IF文でインデントをした場合の事例
1 2 3 4 5 |
#インデント時のエラー File "test.py", line 7 print("よかったね") ^ IndentationError: unindent does not match any outer indentation level |
図:インデント時の文字数相違のエラー
Switch Caseのような構文がない
Pythonには他の言語にあるようなswich文がありません。よって、1度に変数の値の条件判定を行うための手段がありません。その理由が「if文だけで可能」という事のようです。シンプルを追求する言語の性質上こうなってるみたい。
そのため、ifとelif、elseだけで構築するのが条件判定文の一般的なやり方になっています。また、IF文はifやelifそれぞれの文の最終文字に「:」を付ける必要があります。
※dictionaryを用意してそこに文字が入ってるか?であったり、elif a in (12,13,14)といったような条件判定方法もあります
1 2 3 4 5 6 7 8 9 10 11 |
a = 12 #IF文で比較する if a == 10: print("10ではないみたい") elif a == 11: print("11でもないようだ") elif a == 12: print("ビンゴ") else: print("ちょっとよくわかりません") |
図:IF文で複数条件判定の事例
For文がえらくシンプル
他の言語の場合、ループはいろいろな種類が用意されています。しかし、PythonではForはforeachに相当するものしかなく、あとはwhile文があるだけ。規定回数だけ回すという一般的なFor文は、rangeという関数を組み合わせて実現するテクニックになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#for文で規定回数回す a = 1 b = 10 for i in range(b): print(i) #while文で回す a = 1 b = 10 while a < b: print(a) a += 1 #dictionaryを回す c = ["tomato","kinoko","sakura"] for dict in c: print(dict) |
図:確かにこれだけあれば十分といえば十分
直接文字に数値を結合出来ない
JavaScriptなどは+演算子だけでどんな文字でも結合できますが、Pythonで同じ事をやってしまうとエラーになります。文字に数値を結合して、例えばループでメッセージを表示するような場合には、必ず数値を文字列に変換してから行います。
1 2 3 4 5 6 |
#for文で規定回数回す a = 1 b = 10 for i in range(b): print(str(i) + "回まわしたよ") |
図:必ず型変換してから結合するようにする
リストに追加する場合には
JavaScriptでは、[]は配列を意味します。Pythonでも同様で呼び名はリストと呼ばれています。ただし、pushではなくappendを使ってこのリストに値を追加してゆくことになります。二次元配列的なものを作る場合も、リストをリストにappendします。結合させる場合には、extendで別のリストをつなげることになります。
二次元リストにした場合はJavaScriptと同様にlist[0][1]で参照することが可能です。
他にも細かい、リストから削除であったり色々とメソッドが用意されています。
1 2 3 4 5 6 |
#for文で規定回数回す c = ["kinoko","tomato","unagi"] c.append("salad") for dict in c: print(dict) |
関数の定義
JavaScriptなどの場合は、function(){}といった形で、関数を定義していたと思います。Pythonではdefというものを使って定義し、初期値なども定義時に設定が可能です。呼び出し方はfunc()といった形で関数名に括弧をつけて呼び出す点は同じです。IF文同様に関数文字の文末に「:」を付ける点や、インデントに注意。
最後に値を返すときはreturnな点もJavaScriptと同じですね。
また、注意点としてPythonの場合、関数のこの引数は基本参照渡しになる点に注意が必要です。
1 2 3 4 5 6 7 8 9 10 11 12 |
#関数で累乗を計算する c = 2 #関数を定義する #乗数の初期値は2 def doubleman(value, kei=2): #係数で累乗を計算して返す return c ** kei #関数を呼び出す #今回は3乗した値を返してみた print(doubleman(c,3)) |
図:引数省略時の初期値も設定しておくとなお良い
例外処理
プログラミングでは必ず通る道が「エラーが発生した時は・・・」の為のエラートラップが必須になってきます。JavaScriptでもTry-Catch-Finallyがそれですね。Pythonではtry-except-else-finallyとなります。例外処理のメッセージはexceptの行で定義したExceptionから引き取って判定します。
また、わざとエラーを発生させる場合には、raise Exception("エラーだよ")といった構文を使うことも可能です。exceptのeに引数の文字列が入ってきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#わざとエラーをおこしてみる c = 10 #エラー処理を施した関数 def errorman(value): try: x = value / 0 except Exception as e: #エラー発生時の処理 return str(e) else: #エラーがなかった場合 return x finally: #最後に実行される print("実行完了") #関数を呼び出す print(errorman(c)) |
図:finallyは最後にかならず実行されます
何もしない・null値
JavaScriptの場合、例えばif文で判定後何もしない場合は何も書かなければよいのですが、pythonの場合は何もしない場合には「pass」と記述すればOKです。記述しないとエラーになってしまいます。
また、null値ですがNoneがそれに該当します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#税金計算 c = 90 #エラー処理を施した関数 def zeikin(value): if c >= 100: #100円以上の場合は課税額を返す return c * 0.08 else: pass #関数を呼び出す print(zeikin(c)) |
図:90円なので非課税となり、Noneが返ってくる。
モジュールの使用
メインとなるpyファイルの他に用意した別のpyファイル内(subfile.py)のものを使いたい場合、Node.jsなどではrequireで直接ファイルのパスを記述する事で利用可能ですが、Pythonではライブラリと同様にimport subfileを利用します。拡張子は不要です。
この時、他のファイルの全てを取り込む場合にはimportでそのファイルの名前を記述すれば良いですが、一部だけを使いたい場合には、from subfile import tomatomanといった形にする事で、subfile.pyの中のtomatomanという関数をロード可能になります。
但しメインのpyファイルとは別に用意したpyファイルがカレントディレクトリ以下の別のディレクトリ内にある場合には、import subdir.subfileといった形でディレクトリ名も指定が必要になります。この辺りのモジュールのロード方法がちょっと独特ですね。
スコープ
いわゆる変数が有効な範囲。JavaScriptではそのモジュールの中に直接記述した変数はグローバル変数としてどこからでも参照と書換が可能です。また、その関数内やブロック内ならばletを使って定義して参照可能な範囲を絞っていました。
Pythonの場合もグローバル変数はモジュールスコープと呼ばれ、そのモジュール内ならばどこからでも参照と書換が可能です。
問題はローカルスコープ。関数内で例えばモジュールスコープと同じ変数を用意して値を代入しても、モジュールスコープは書き換わらず、その関数内でだけ宣言された、つまりletで宣言したものと同じ意味をなします。よって、以下のようなコードの場合、モジュールスコープは書き換えられることなく実行結果が出ます(同名の全く別の変数扱いになる)。
もちろん、外部から関数内で宣言した変数を参照する事はできません。この時、モジュールスコープで変数がない場合には、NameError: name 'a' is not definedといったエラーがprintの行で発生してしまいます。モジュールスコープの変数を書き換えたいならば、モジュールスコープと同じ領域内でないと書き換えができないわけです。JavaScriptとはここが大きな違いになります。
※但し、クロージャのような形式をとった時だけは、内部関数内の変数にnonlocalを付け加えると、内部の関数からは、一個外側の変数(親の関数内)を読み書き出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#モジュールスコープを宣言 a = "tomato" # def myfunc(): a = 'kinoko' print(a) #関数を呼び出してみる myfunc() #関数内の変数を参照してみる print(a) |
図:kinokoとtomatoの2つの値がprintされる
様々なライブラリ・フレームワーク
Pythonには様々なライブラリやフレームワークがあるので、ゼロから全部を自分で構築する必要はなく、またそれが故に最低限のコードで組み合わせて構築できる良さがあります。スクレイピングなども可能なのですが、正直Puppeteerも使えるNode.jsのほうがPythonよりも有利かなと思います。
デスクトップアプリ
PyQtやTKinterなどのライブラリもあるのですが、GUIもPythonコードで構築する必要があり正直な所使いたいと思いません。一方でNode.jsの場合、NW.jsやElectronといったフレームワークがあり、HTML+CSSでGUIを構築出来ます(フロント部分の挙動はJavaScriptが必要ですが)
そんな中探してみた所、Eelと呼ばれるHTML+CSSでGUIを構築できるライブラリや、PyWebViewと呼ばれる同様のライブラリがありました。PythonでGUIを構築するよりも、HTML+CSSのほうが学習コストは低めです。何よりもHTML側でBootstrapなどのJavaScriptライブラリで表現したほうが圧倒的にコントロールしやすいです。
JavaScriptを学ぶ必要性があるという点ではコストが掛かるのは事実ですが、Python上でGUIを作るスキルは他で流用が効くものではないので、時間を掛けてもHTML5でGUI構築がオススメです。
ウェブアプリケーション
ウェブアプリケーションとなると、社内向けのものであればGoogle Apps Script + Vue.jsが最も手頃だしサーバレスでできるのでオススメなのですが、Pythonでとなると、サーバが必要となります。そこで作るとなるとGoogle Apps ScriptのようにバックエンドにPythonを用意し、テンプレートとなるHTMLが必要です。
ただ、JavaScriptが不要になるわけではないので、注意。クライアントサイドのUIや動的な表現はPythonで出来ません。
軽量なテンプレートエンジンとなると、Flaskが有名です。重量級で多機能で有名なのはDjango。これらは大手のウェブアプリケーション(YoutubeやInstagramなど)で使われてる事でも有名ですね。本格的なウェブサービスをPythonで提供する際に避けて通れないものでしょう。
一方でリアルタイム通信(WebSocket)に対応してるものとしてTornado、pythonファイル一個で実現できるBottleなどなど。入門ならBottleが良いのかもしれません。
個人的にはウェブアプリケーション構築ならば、Node.jsのほうが良いんじゃないかなぁと思いつつ。
データ解析
Pythonが今注目されている分野の一つがデータ解析。昔からあるデータマイニングやらデータウェアハウスやらといったものですね。その中でもデータ解析をしてグラフにプロットするものとして有名なのがMatplotlibです。
業務用としては、Tableauと連携して動作するTabPyになるでしょう。もちろん、Google Data PortalにつながるBigQueryと連携する公式ライブラリであるgoogle-cloud-bigqueryを使うというのも面白そうです。tableauとPython連携はこちらの記事が面白そうです。
※Tableauの場合には、.trexファイルを作成してデスクトップやオンラインなどに拡張機能という形で追加することが可能のようです(言語はどうやらJavaScriptみたい)。拡張機能のGUI部分はHTML5で構築が可能のようで、バックエンドはPythonやR言語を使う形みたい。まだアカウント貰ってないので、もらえたら徹底的に分析してみたいと思う(過去に酪農経営シミュレータや医薬品卸価格解析ツールで培ったものを盛り込みたいなぁ)
機械学習
ディープラーニングやらAIやら世間で言われてるアレですね。但し、機械学習そのものは非常に高度な領域なので、ライブラリを入れれば簡単に装備できるといったシロモノじゃありません。それを行う準備そのものも、莫大な基礎データが必要になりますが、これは全て自分で用意しなければなりません。
この分野で機械学習を構築したいとなると、数値計算担当のNumPy、テーブルデータ操作を担当するPandas、Facebookが作成してるPyTorch、Google謹製の機械学習環境であるTensorflow、同じくTensorflowを提供してるCloud ML Engineなどなど。
実際にTensorflowできゅうりの等級判定の為にTensorflowを利用した自動仕分け装置を作り、人手不足の農業の現場に於いて、仕分けの自動化を実現した人の話は非常に有名ですね。
関連リンク
- Pythonプログラムが遅い!高速化したい!そんな時は...
- Pythonのパッケージ管理システムpipの使い方
- WindowsユーザーはPythonランチャーの存在を意識しましょう
- 4. precompile standard library とは(Pythonインストール)
- Python 3 インストール
- 【Python入門】ダウンロード数トップ10のライブラリを解説
- Python 日付、時刻の処理
- Pythonメモ : あまり知られていない(かもしれない)テクニック集 その3
- Pythonの引数における参照渡しと値渡しについて
- PyWebViewでBootstrapを使用したUIを作り、PyInstallerでEXEにする
- 【Python入門】Matplotlibを使ってみよう
- TabPyをインストールしてみた #tableau
- ダッシュボードの拡張機能の使用 - Tableau
- Tableau Developers Club Season 2 /*TableauのAPIすべて*/ Extensions API編 #1 + 忘年会
- 機械学習入門 - 基本のPythonライブラリ、9つを触って学ぶ
- kerasを使ってみよう