1日で習得する Python 入門 研修コースに参加してみた
今回参加したコースは 1日で習得する Python 入門 です。
基本情報技術者試験でも採用されるぐらい一般的になった Python 。本屋に行けば Python の本だらけですよね。
とはいえ、Python に限ったことではありませんが、プログラミング言語にはそれぞれ独特の “クセ” があり、たとえ何らかのプログラミング言語の経験があったとしても、新たなプログラミング言語を学ぶというのは敷居は高いものです。
このコースは、そんな「 Python を学んでみたいけれど…」と二の足を踏んでいる方に、ぜひおすすめしたいコースです!!
では、コース内容をレポートします!!
もくじ
コース情報
想定している受講者 |
|
---|---|
受講目標 | Python プログラミングの基本を理解し、簡単な Python アプリケーションを作ることができる |
講師紹介
このコースで登壇されたのは 米山 学さん です。
JavaはもちろんPython/PHPなどスクリプト言語、Vue/ReactなどJSだってなんだってテックが大好き。原点をおさえた実践演習で人気
Python を学ぶべき理由
研修を始めるにあたって、「 Python を学ぶべき理由」について説明いただきました。
- Google Trends における人気
- C# や Java の人気が横ばい、または下がり気味である
- Python は JavaScript と並んでもっとも人気の高い言語
- 理由はビッグデータの統計解析処理や機械学習といったデータサイエンス分野、Deep Learning や AI なのでの利用が増えていること
Python の学習用ドキュメント
Python の学習に先立ち、学習で使うドキュメントとなるサイトをいくつかご紹介いただきました。
なお、このうち、Python Weekly のニュースレターをサブスクライブ (購読) すると、最新情報が受け取れるそうです。
インストール
バージョンの違いに注意
- 2 系と 3 系がある
- 困ったことに互換性がない
- 混ぜるな危険
- 3 系でやるほうがよい
- 2.7 でリリースが終了と 2011 年にアナウンスされている
- ライブラリも 2 系のサポートを終了
- 今回は 3 系でやります
- Pythonのダウンロードページ(英語)
- Windows x86-64 executable installer を使用
Python が正しくインストールされたかどうか、確認します。
> python --version
Python 3.8.1
簡単な Python プログラムの実行
コマンドプロンプトやターミナルで「 python 」コマンドを実行すると、REPL が起動し、コマンドラインで Python のプログラムを実行することが可能です。さすが、インタープリタ型です。
> python
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
ということで、このままコンソールに「Hello Python!」と表示してみましょう !!
>>> print("Hello Python!")
Hello Python!
また、 print()
は、カンマ区切りで複数の引数を取り、連結して出力できます (便利!!) 。
>>> print("Hello", "Python!")
Hello Python!
デフォルトのセパレータは(スペース)ですが、これもオプションをつけると任意の文字に変えられるとのこと。
>>> print("Hello", "Python!", sep='_')
Hello_Python!
その他にも様々なオプション引数があると、紹介いただきました。
sep
- セパレータを任意の文字列に変える
end
- 出力の終わりに自動で付加される改行コードを付加しない
# sample.py を作成->記述
print("Hello ", end='')
print("Python!")
> python sample.py # コンソールから sample.py を実行
Hello Python!
なお、Visual Studio Code では[ Ctrl ]+[ @ ]キーでコードを実行できます。
プログラミング学習では、さまざまなプログラムを何度も実行するので、ぜひ覚えておきたいテクニックですね。
Python 書き方
他言語との違い
- 他の言語との違い
- セミコロン
;
は終末にいらない - コロン
:
とインデントでブロックを書く - 慣れが必要
- セミコロン
- 慣習規約
- コーディング規約は PEP 8 に目を通しておくとよいですよ
- 慣習規約は守らなくてもよいが、誰でも読めるので、そっちのほうがよいです
- ファイル名はスネークケースで書くのが基本 (ただしクラス名などはキャメルケースになったりするので下の表を参考に)
- file_program.py
- そのほか細かい規約があるので注意
- コーディング規約は PEP 8 に目を通しておくとよいですよ
パッケージ | 全小文字(なるべく短くアンダースコア非推奨)matplotlib.py |
---|---|
モジュール | 全小文字(なるべく短くアンダースコア可)matplotlib.show() |
クラス | 最初大文字+大文字区切り MyFavoriteClass |
例外 | 最初大文字+大文字区切り MyFatalError |
型変数 | 最初大文字+大文字区切り MyFavoriteType |
メソッド・関数 | 全小文字+アンダースコア区切り my_favorite_method |
変数 | 全小文字+アンダースコア区切り my_favorite_instance |
定数 | 全大文字+アンダースコア区切り MY_FAVORITE_CONST |
見た感じ PHP などのスクリプト言語っぽい規約ですが、開発チーム内で不毛な論争にならないためにも IDE やエディタに Lint ツールを入れて慣らしたいところですね。
コメント
- 単行コメント
print("hoge") # コメント
- シングル
' '
もしくはダブルクォーテーション" "
で囲むと複数行コメント''' コメント コメント ''' """ コメント コメント """
どちらもコメントとして扱われます。なお、コメント記号もインデントを揃える必要があり、揃っていないとエラーになります。
演算子
他の言語と違って特徴的なところを紹介いただきました。
- 算術演算子: べき乗は
**
で記述 - 算術演算子: インクリメント
++
/ デクリメント--
が存在しない - 比較演算子: オブジェクトが等しい
is
/ オブジェクトが等しくないis not
が存在する - スペース区切りでも文字列を接続できる
>>> str = "a" "b" "c" >>> print(str) # abc と出力される
+
で文字列を繋げる処理が異なる# sample.py を作成->記述 str = "a" + 1 print(str)
> python sample.py # sample.py をコンソールから実行 Traceback (most recent call last): File "c:/Users/UserName/test.py", line 1, in
str = "a" + 1 TypeError: can only concatenate str (not "int") to str *
演算子を使用すると、文字列を繰り返し出力可能str = "abc" print(str * 3) # abcabcabc と出力される
変数とデータ型
- 型宣言は不要
- 実行時に判定される
- ただし、以下のように num は int と思っていると、勘違いしてしまうケースも出てしまう
- 潜在的なバグを生むので注意が必要
num = 0
str = "abc"
num = str # 静的言語ではここでエラーになる
print(num) # abc が出力されてしまう
文字列リテラル
"文字列"
or'文字列'
どちらでも OK- 変数を埋め込む場合は
{ }
で変数を囲む- f文字列と呼ばれる
name = "John"
print(f"My name is {name}.") # My name is John. が出力される
これは使いやすそうな印象を受けますね
None (NULL)
- None と表現される
- 存在しない、未定義と表現される
- この 未定義 があるというのが特徴
- is 演算子で判別する
- = や ≠ では判定できない
obj = None
print(obj is None) # True
print(obj is not None) # False
制御構造
if 文
- そんなに他と変わらない
a = 1 if a == 1: print("OK") # true の処理。ちなみに、インデントをしっかりしないとエラー
- 条件の書き方が独特 (数学的)
if 1 < a < 5:
if-else 文
- これもそんなに他と変わらない
a = 1 if a == 1: print("OK") else: print("NG")
多重分岐 if-elseif-else文
- ここがちょっと注意ポイント!タイプミスしがち
- elseif と書かず elif と書く
a = 1 if a == 1: print("OK1") elif a > 0: # elif と書くことに注意 print("OK2") else: print("NG")
- elseif と書かず elif と書く
- ちなみに switch case はありません!(あらら)
- Python は同じ処理を複数でかけるように していません (あららら)
- なので forech が無かったりします! (あらららら)
繰り返し for
- for と言いながら、foreach と同じような動きをする
- for のように書きたい場合は違うように書く
- rang 関数を併用する
for i in range(5): # 0 からカウント print(i)
- 引数を持てるので、オフセットも指定できる
for i in range(5, 10): # 5 以上 (含むので注意が必要) 10 より下 print(i)
- 注意が必要なのはブロック外にも適用される
- バグになりやすい
for i in range(5): print(i) print("[OUT]", i) # 他の言語ならエラーだが [out] 4 が出力される
- バグになりやすい
慣れてくれば、こちらのほうが見やすくてき書きやすい感がありますが、、、最後のはセミコロンで終末を区切らないので、かなり注意が必要に感じます。
あとは 繰り返しの while についても触れました。
i = 0;
while i < 5:
print(i)
i += 1 # インクリメントの演算子 += -=
繰り返しで else が使えるぞ
- 繰り返したあとの処理を書ける
- python ならではの書き方
- break を併用した場合、break で抜けなかったときに実行される
for i in range(5): print(i) if i > 3: # ここを 5 にすると else に入る break else: print("end") # 実行されない
データ構造 ~汎用組み込みコンテナ~
汎用組み込みコンテナ。 ちょっと雰囲気が異なる言葉ですね。
- 他言語ではコンテナと呼ばれるデータ構造
- 配列など
- ちなみに、 python には配列がない (!!)
- list だけでやっている
- 配列の扱いをしているケースが多いが、厳密には違う
配列 ? のような感じかなぁと思っていると、多様な表現があり、数学などを扱う Python らしさが垣間見えました。
list
- list は可変長配列でオブジェクト
- 0 スタート
list()
で生成しappend()
で追加my_list = list() print(my_list) # => [] my_list.append(1) my_list.append(2) my_list.append(3) print(my_list) # => [1, 2, 3] print(my_list[0]) # => 1 print(my_list[1]) # => 2 print(my_list[2]) # => 3
- 簡単にも書ける (こっちのほうが使われているかな)
my_list = [1, 2, 3] print(my_list) # => [1, 2, 3]
スライス
Python というとスライスはよく聞く単語ですよね。伺っていると、私自身の感覚では配列へのアクセス方法のように見えました。
- list の中で範囲指定ができる
list[min_index, max_index]
- 略すことができる -> min を外せば最小値、max を外せば最高値
print(my_list[0:2]) # 0 以上 2 未満を返す print(my_list[-1:-3]) # - を使うときは注意。-1 はより下はないので何も返さない
他に書き換えなどのメソッドがあるとのことでした。
多次元配列
- 他とあまり変わらない
my_list2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] print(my_list2[1][2]) # => 6
- 2 重ループを書いてみよう
for l in my_list2: # [[1, 2, 3], [4, 5, 6], [7, 8, 9] のそれぞれの list が出てくる for i in l: print(i, end='') print()
list ではない配列 Tuple
- tuple は変更できない (イミュータブル)
- 定数として使いたいときに効く
- 後述する key-value 型の dictionary のような場合、 key が変わらないものとして使いやすい
()
で定義するt = (1, 2, 3) # ()は省略可能 t[0] # => 1 t[0] = 2
これはエラーになる
TypeError: 'tuple' object does not support item assignment
- なお
()
を省略できることによって、間違ってx = 1,
とすると int 型ではなく tuple 型になる
重複しない要素を扱う set
表現を見ていると、配列と変わらんイメージですが、 "集合" というのがミソです。
- 数学の集合のようなものを扱うのが set
set()
か{}
で生成できる- Java の人は {} に注意。配列じゃないよ
s = {1, 2, 3} s.add(3) # 重複しているので無視される s.add(4) # 要素の追加 print(s) # => {1, 2, 3, 4} s.remove(2) # 要素の削除 print(s) # => {1, 3, 4}
このコースでは時間的な制約から実際の演算を行いませんでしたが、実際には集合演算によく使われます。
s1 = {1, 2, 3}
s2 = {3, 4, 5}
print(s1 & s2) # => {3} が出力される。& は積集合 (両方に含まれるもの) の演算子
連想配列? Map? dict (dictionary)
きました、dict 。これも Python というとよく聞くやつです。
見てみると連想配列のようで見慣れた感じで、ふふーん♪ と思っていると、データの取り出し方が独特でした。
- 一意な Key - Value のペア
{key: Value}
で定義keys()
,values()
で取り出せる- アクセス方法は
[]
で指定d = {1: 'A', 2: 'B', 3: 'C'} print(d) # => {1: 'A', 2: 'B', 3: 'C'} print(d.keys()) # => dict_keys([1, 2, 3]) print(d.values()) # => dict_values(['A', 'B', 'C']) print(d[1]) # => A
- for 文で取り出す場合は、よくある言語と違う
- デフォルトでは key だけが取り出される
d = {1: 'A', 2: 'B', 3: 'C'} for key in d: print(key) # => 1 2 3
- 値を取りたいときは
values()
を使うd = {1: 'A', 2: 'B', 3: 'C'} for val in d.values(): print(val) # => A B C
- デフォルトでは key だけが取り出される
- key と value を両方取りたいときは
items()
を使う- 変数を 2 つ用意する
- tuple オブジェクトで返ってくる
- 変数 1 つで指定すると、
(1, 'A')
のように返ってくるd = {1: 'A', 2: 'B', 3: 'C'} for key, val in d.items(): print(key, val) # => 1 A 2 B 3 C
- 変数 1 つで指定すると、
内包表記
いつもいつも Python のコースでは戸惑ってしまうやつなのですが、今回は比較して説明いただいたので、理解できました!(出来るとは言ってない)
そして、便利っぽい!!(出来るとは言ってない 2)
- 関数型ならではのデータ「表現」
- 論理学における内包
- list でよく使われる
- 内包表記を使って、変数を変えさせない、ということができる
- 普通の表現
list = [] for x in range(5): list.append(x) print(list) # => [0, 1, 2, 3, 4]
- 内包表記
- 記述がシンプル
- append よりもパフォーマンスがちょっとよい
list = [x for x in range(5)] print(list) # => [0, 1, 2, 3, 4] print(x) # NameError: name 'x' is not defined
- zip 関数を使って key と value を結合させるのが実践的な使い方
key_list = ['A', 'B', 'C'] val_list = [1, 2, 3] d = {k: v for k, v in zip(key_list, val_list)} print(d) # => {'A': 1, 'B': 2, 'C': 3}
関数を書いてみよう
いよいよプログラミングらしくなってきました。
def
で定義する- だいたい他の言語と同じ
- 引数の受け取り方 と 高階関数 に特徴がある
- 空の関数は定義できない
- 処理のところに pass を書く
- 引数あり、戻り値なし
def func(i): pass # 呼び出し func(1)
- 引数あり、戻り値あり
def func(i): return 0 # 呼び出し rtn = func(1)
デフォルト引数
- 呼び出すときに引数が指定されていなくても初期化する書き方がある
def func(x=1): # デフォルト引数は PEP 8 では x = 1 とスペースを使わない print(x)
キーワード引数
- おそらく下のコードを見たほうが速い
def func(x, y, z): print(x, y, z) func(1, 2, 3) # => 1 2 3 func(z=3, x=1, y=2) # => 1 2 3
- 混在させるときは キーワード引数が後にくる
func(x=1, 2, 3) # エラー
- 可変長引数 (任意の値を受け取る) の書き方
*
で定義するdef func(x, y, z, *args): for arg in args: print(arg) func(1, 2, 3, 4, 5) # => (4, 5)
- 可変長の dict (key-value) を受け取る
**
で定義するdef func(**args): print(args) func(x=1, y=2, z=3) # => {'x': 1, 'y': 2, 'z': 3}
高階関数
この高階関数を紹介するにあたって、関数型プログラミングの特徴も紹介いただいたのですが、これは別レポートにも書いていますので、ここでは割愛します。
内包表記に続き、これまた毎回つまづくやつですが、研修後に米山さんに聞いて、なんとか理解できました!
ちなみに、わたしにとって恐らく再帰っぽい表現が苦手になる理由な気がします。
- 関数型プログラミングの影響をうけて、関数をうけて、関数を返す
- 共通処理だけ書いて、差分を別関数に出す、ということができる
- オブジェクト指向の継承っぽい ?? (私の質問)
- オブジェクト指向ではないが、モジュールの拡張というのが趣旨 (米山さんの回答)
- 共通処理だけ書いて、差分を別関数に出す、ということができる
- 関数を受け取る関数
def x(f): print("x: ", end='') f()
- 関数を返す関数
def y(): def z(): print("z") return z
- 高階関数を使う
def test(): print("test") x(test) # x 関数から test 関数を読み出す f = y() x(f) # => x: z
とはいえ、何回聞いても、ややこしい~
ラムダ式
高階関数がわかってないと、わからないやつです。つまり、私は輪をかけて苦手です。。
- 高階関数をより強力に表現できる
- 具体的には無名関数を表現しやすい
- 普通の関数 -> ラムダ式
def 関数名 (引数): 処理
arrow_downward
lambda 引数: 処理
ここで map 処理 を例に何をしているのか、トレースして頂きました。
print(list(map(lambda x: x * 2, [1, 2, 3]))) # => [2, 4, 6]
- map 関数に lambda 式含め、引数が 2 つあり、2 番目の引数を 1 番目の引数に渡す
- lambda の戻り値は x * 2
- list 関数が map 関数を呼び出す
- list にする
- print 関数が list 関数を呼び出す
- list を表示する
もうひとつ高階関数 with lambda 式を眺めてみましょう。
print(list(filter(lambda x: x % 2 != 0, [1, 2, 3]))) # => [1, 3]
- filter 関数は 1 つめの引数を 2 つめの引数から除外する
- lambda x: x % 2 != 0 で 0 を除く、偶数を戻す
- filter 関数で [1, 2, 3] から偶数を除く
丁寧にトレースいただいたおかげで、読みやすくなりました!
そのほかに 高階関数の一つ デコレータ関数 についても紹介いただきました。
オブジェクト指向プログラミング
続いて学習するのは、オブジェクト指向プログラミングです。
ちなみにオブジェクト指向と関数型、どちらも使えるのは Python の特徴かと思っていると、スクリプト言語はだいたい使えますね。
JavaScript に PHP 、Ruby などいずれもそうです。Perl は、、、いえ、ググってみると Perl もそうでした。
クラス
- Java でメンバ変数、メソッドと言っているのが、Python ではデータ属性、メソッド属性という
- 第 1 引数は自分自身を表す引数を取らなければならない
- そのときは
this
ではなくself
を使おうと PEP 8 では言っているclass Foo: def x(self): # Python ではインスタンス変数は宣言する必要がない print("x")
- そのときは
- getter, setter でもうちょっと慣れよう
class Foo: def set_x(self, x): self.x = x def get_x(self): return self.x
- Foo クラスを使う
foo = Foo() foo.set_x(1) print(foo.get_x()) # => 1
コンストラクタ (初期化処理)
__new__(cls)
でクラスを初期化してインスタンスを生成- インスタンスの生成を書いてやる必要がある
__init__(self)
でインスタンスを初期化- インスタンスの初期化を使うことのほうが多い
class Foo: def __new__(cls): print("new") def __init__(self): print("init") foo = Foo() # new しか表示されない
- インスタンスが生成されていないので、self に値が渡っていない。
インスタンス生成の処理を入れる ( super クラスを使う)class Foo: def __new__(cls): print("new") return super().__new__(cls) # インスタンスを生成 def __init__(self): print("init") foo = Foo()
- インスタンスの初期化を使うことのほうが多い
クラス・メソッド
ほとんどの言語では、 new
(インスタンス化) してメソッドを呼び出しますが、Python は new しなくても呼び出せます。
研修ではスタティック・メソッドを紹介しながら、このクラス・メソッドを取り上げました。
- Python 特有のもの
- 基本的に、クラス変数にアクセスする場合は class メソッドを、アクセスしない場合には static メソッドを使う
- クラス・オブジェクトを指定して、変数やオブジェクトを参照する
class Foo: val = "class_variable" # クラス変数 @classmethod def class_method(cls): # クラスメソッドの引数は cls ( Pep 8 より) print(cls.val) # => class_variable
カプセル化
- 変数の前に
__
を追加するclass Foo: def set_x(self, x): self.__x = x
継承
( )
内に継承するクラスを書く- 多重継承ができる (!!)
- 同じメソッドがクラス内に書かれていた場合、左のクラスが優先される
class Bar: def x(self): print("x") class Baz: def y(self): print("y") class Foo(Bar, Baz): # 多重継承: Bar と Baz を継承 pass foo = Foo() foo.x() # => x foo.y() # => y
- 同じメソッドがクラス内に書かれていた場合、左のクラスが優先される
その他、サブクラスからスーパークラスを呼び出すときの書き方も紹介いただきました。
例外処理
- 実際やってみましょう
-
a = 1 / 0 # ZeroDivisionError: division by zero print("OK") # 表示されない
-
- 表示されないということはプログラムが強制終了されている
- 強制終了ではなく、正常な状態に戻そうとする -> それが例外処理
- 他言語と同じく
try
を使うcatch
ではなくexcept
を使うtry: a = 1 / 0 except ZeroDivisionError: print("Don't divide by zero.") print("OK")
- 複数の例外に対応
try: list = [] list[0] = 1 # IndexError a = 1 / 0 # ZeroDivisionError except Exception as ex: print("[ERROR] Something exception has occured.") print("[REASON]", ex) print("OK")
- エラーすべてに対応
try: list = [] # tuple を使う list[0] = 1 # IndexError a = 1 / 0 # ZeroDivisionError except Exception: # Exception というスーパークラスに入る print("[ERROR] Something exception has occured.") print("OK")
- 例外のスロー ( throw ) は raise 文を使う
a = 1 if a == 1: raise ValueError ''' # 実行結果 --------------------------------------------------------------------------- ValueError Traceback (most recent call last)
in 1 a = 1 2 if a == 1: ----> 3 raise ValueError ValueError: ''' - ユーザー定義の例外は Exception クラスまたはそのサブクラスを継承
class MyException(Exception): def __init__(self): self.message = "User defined exception" try: raise MyException except MyException as ex: print("[ERROR]", ex.message) print("OK")
Pythonにおけるパッケージ管理
- ライブラリのことを モジュール や パッケージ と呼ぶ
- import 文を使う
import sys print(sys.platform) # 実行プラットフォーム print(sys.version) # Pythonのバージョン情報
- ただ、これでは特定のモジュールを指定するのが、ちょっとメンドイ
- from を使うとよい
from sys import platform from sys import version print(platform) print(version)
- from を使うとよい
pip を使う
- js における npm 、Ruby における gem 、 PHP における composer と同じ扱いで、Python には pip がある
- pip インストールやパッケージ更新など pip コマンド
pip install package_name # インストール pip install -U package_name # アップデート pip uninstall package_name # パッケージの削除 pip list # パッケージの一覧 pip install -U package_name # パッケージの更新
- pip そのもののアップデート
python -m pip install --upgrade pip
どうでもいいですが、ピップ、かわいい響きです。
以上、盛りだくさんに入門してきたのですが、ここで終了の時間を迎えました。
最後に米山さんから、今日やるつもりで用意頂いた「 Flask による Web アプリケーションの作成」をあらましを紹介いただきました。
受講者向けに公開されている Dropbox Paper のコーステキストを見ると、薄い Flask らしい本当に簡単なチュートリアルを用意いただいていました。
( Python で同じく有名な Django だと、フルスタックで重厚なだけに内部構造 ( src の構造、配置など) をまず理解する必要があります)
ちなみに、先日参加した 一休.com のセッションでも Flask を採用し、やり方が制限される Django より柔軟に、拡張できるのがその採用理由と紹介されていました。
まとめ
このコースでは、Python の基礎を 1 日がかりで学びました。
人気のある言語だけに、公式ドキュメントをはじめ、インターネット上の記事、書籍などたくさんのコンテンツがあり、独学しやすそうですが、一方で環境構築でコケたり、なかなか時間が取れなかったり、つまづくポイントはたくさんあります。
1 日と決して長くない時間ですが、他言語との差分を中心に、たくさんのサンプルコードをオンラインで用意頂いて挙動を試せましたので、言語構文の基礎をテンポよく学べました。
「そろそろ、やるか」のまま入門書や本が積ん読になってしまっている方、「本気だす」きっかけがほしい方にはピッタリです!
ちなみに、、、
このコースで学んだことをもって、基本情報技術者試験 Python の問題を見ると、「読めるぞ~」となるので、オススメです。
label SE カレッジの無料見学、資料請求などお問い合わせはこちらから!!
label SEカレッジを詳しく知りたいという方はこちらから !!
IT専門の定額制研修 月額28,000円 ~/ 1社 で IT研修 制度を導入できます。
年間 670 講座をほぼ毎日開催中!!
SEプラスにしかないコンテンツや、研修サービスの運営情報を発信しています。