1.関数の基本
(1)関数について
関数はあらかじめ作成されているものもあれば、自分で作ることもできる。
len() や sum() なども事前に組み込まれた関数で、たとえば、引数を関数に渡すと、値を返してくれる。
関数を使うことで、毎回処理を書く必要がないので、楽である。
あらかじめ作成されている関数は以下に記載がある。
https://docs.python.jp/3/library/functions.html
先に紹介したtypeもその一例
>>> a=2
>>> print(type(a))
(2)関数の作成
・def 関数名:
処理
【注意点】
・defはdefine(定義する)の意味
・小文字のアルファベットで作ろう。先頭に数字はダメだったはず。
・スクリプト言語なので、上から順に実行される。関数の順番にも注意が必要
単純な例を作ります。helloという関数を作り、hello()で呼ぶ。ただこれだけ。
❶関数を使わない場合
以下はLinux上で実行している。単にprintしているだけ。
・hello.pyのソースコード
#!/usr/bin/python print('hello')
・実行結果
# ./hello.py hello
❷関数を作ってみる
・ソースコード (Linux類は抜いた)
def hello(): print("Hello!!")
・実行結果
# ./hello2.py
このように何も表示されない。というのも、関数hell()を定義しただけで、その関数を実行していないからだ。
では実行するにはどうすればいいか。以下のように、hello()関数を呼ぶ。
・ソースコード
def hello(): print("Hello!!") hello()
・実行結果
# ./hello2.py Hello!!
(3)引数を渡す
・プログラムを処理するときは、入力データがあって、それを演算して結果を出すということが多い。そのために、引数を渡すことができる。先ほどの引数は、引数がなかったので()としてあった。
・引数の渡し方
位置引数とキーワード引数の2つがある。位置は文字通り、場所が対応する。
キーワードも文字通り、value=などと引数のキーワードを指定する
・以下は、aとbの積を求めるsekiという関数を作った。そして、print(seki(3,4))にて、3と4という引数を渡し。戻って来た結果(return)をprintしている。
#!/usr/bin/python def seki(a,b): return a * b print(seki(3,4))
・引数をaやbに渡しているが、名前は何でもいい。name_bなどと長い文字でもいい
・戻り値をreturnで返せる。※returnの後の処理は実行されない。
・ return a * b のところは、 c = a * b として、 return cとしてもいい。
・細かい話だが、a*bとスペースを入れなくてもいい。
❶例として、値を入力し、その値の2倍を返すプログラムを作る
・bai.pyというプログラム
#!/usr/bin/python # -*- coding: utf-8 -*- def bai(x): #これが関数 y=x*2 return y #2倍にして返り値をyとして返す print("数字を入力してください") #画面に表示 x=int(input()) #入力された文字をxに入れる。intにしておかないと、文字列として扱われてしまう z=bai(x) print(z) #として受け取った返り値を表示する
実行結果として、5を入力した場合、2倍になって10と表示されている。
# ./bai.py 数字を入力してください 5 10
❷pass
何も処理しない場合はpassを使う。何も処理しない。関数をprintしてみると、Noneが返ってくる。
def fun(): pass fun() # →何も表示されない print(fun()) # →Noneが表示される。
❸引数を指定する
最後の行にあるように、引数の項目を指定すれば、順序が逆になっても可能
def func(name,age): print(name,'is',age) func('Ito',23) #==>Ito is 23 func(age=21,name='Kato') #==> Kato is 21
また、必要な数の引数を受け取らないと、エラーになる。
(4)可変個の引数を渡す
本来、必要な引数の数だけ渡す必要があるが、引数がいくつか不明な場合もある。
以下は2つ目が引数の数が合わないと怒られる。
def func1(i): print(i) func1('aaa') func1('123', '456')
そのときは、アスタリスク(*)を使うことができる。結果はタプルで返される。
❶可変個の引数
def func(*arg): print(arg) func('abc') #==>('abc',) func('abc','de') #==>('abc', 'de') func('abc','de','f') #==> ('abc', 'de', 'f')
❷通常の引数と組み合わせることも可能
def func(x,*arg): print(x,arg) func('abc') #==>abc () func('abc','de') #==>abc ('de',) func('abc','de','f') #==>abc ('de', 'f')
ただ、上記のように、タプルで返してくるので、出力は工夫した方がいいかも。たとえば、以下。
def func(x,*arg): print(x, *arg) #==>abc,de,f print(x, *arg, sep=",") #==>abc de f func('abc','de','f')
❸辞書の場合
アスタリスク(*)を2つ付ける。
辞書型なので、引数を指定するには、key=valueの形にで書く
def func(**arg): print(arg) func(x=1,y=2,z='abc') #==>{'x': 1, 'y': 2, 'z': 'abc'}
(5)引数の初期値
初期値を入れる例をみてみよう。関数funcを2回実行していて、1つは値を渡す場合、2つ目は値を渡さないので、初期値が反映される。
i = 'Hello' def func(x=i): print(x) func('Ya!') #==>Ya! func() #==> Hello
2.応用
(1)グローバル変数
関数で定義される変数は、関数の中だけで利用されるローカル関数。
あまりないと思うが、関数内でグローバル変数を宣言したい場合は、global を使う
(2)リストの引数、辞書型の引数
リスト型の引数を渡す場合は*をつける
辞書型の 〃 ** 〃
(3)リストの引数、辞書型の引数
リスト型の引数を渡す場合は*をつける
辞書型の 〃 ** 〃
3.関数のモジュール化とパッケージ化
(1)関数のモジュール化
まずはやってみよう
必要な関数は部品として別ファイルにしておくと便利だ
実際に作ってみよう。以下のm1.pyは、受け取った値を2倍にして返す関数
・m1.py
def bai(x): return x*2
・メインの関数。つまり実行するファイルは以下のpg1.py
import m1 #m1.pyというファイルをimport print(m1.bai(3)) #m1のbaiという関数を実行する
→結果は6と表示される。
(2) if __name__ == '__main__': について
❶概要
・__name__は、定義しなくても最初から存在している変数である。
・__name__には、実行しているモジュールの名が入る。
・プログラムが書かれているファイルで実行した場合、自動で__main__が入ります。
・他のプログラムから呼ばれたモジュールの場合、そのモジュールの名が入ります。たとえば、mod1.pyのモジュールを呼んだ場合、mod1が入る。
❷順番に実施していこう
print(__name__)
結果は以下
__main__
つまり、__name__という変数には__main__という値が入っている。
❸if __name__ == '__main__':の意味
__が入っているからわかりにくいが、単に、変数__name__ が入っていると考えるといいだろう。
つまり、自分のモジュールの場合だったら、ということだ。他のモジュールから呼ばれた場合には実行しない。
自分のプログラムか他から呼ばれたのかを判断するための仕組み。
なので、以下の2つプログラムpg1.pyを実行すると、同じ結果を表す
print('hello')
・こちらは、ifからの内容を入れた場合
if __name__ == '__main__': print('hello')
➍モジュールを呼んでみよう
たとえば、以下のm1.pyというファイル(プログラム)がある。
・直接実行する場合
if __name__ == '__main__': print("Hello") def bai(x): return x*2
これをこのまま実行すると、実行している自分自身だから、変数__name__ には__main__が入っている。よって、printが実行されて結果は以下
Hello
・モジュールを呼び出して実行する場合
pg1.pyからm1.pyというファイルを呼び出す
import m1 print(m1.bai(3))
すると、関数baiだけが実行されて、printは実行されない。
6
以下は続き
qiita.com
(3)モジュールのインストール
・以下のようにしてインストールする
pip install janome pip3 install janome
インストールされているリストを表示
pip list
(4)標準モジュール
❶sysモジュール
・インタプリンタにビルトインされているモジュール
・import sys を使う。
以下、ps1とps2には、標準プロンプトが入っている。これを変更すると、以下のようにCisco
スイッチのようなプロンプトに変更することもできる。
>>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... ' >>> sys.ps1='Switch> ' Switch>
❷dir()関数
sysがどんなモジュールを定義しているのかを確認するために、dir()を使う。先ほど使ったps1やps2も見つけることができた。
>>> dir(sys) ['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__', '_base_executable', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_enablelegacywindowsfsencoding', '_framework', '_getframe', '_git', '_home', '_xoptions', 'addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', 'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'getallocatedblocks', 'getdefaultencoding', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'platlibdir', 'prefix', 'ps1', 'ps2', 'pycache_prefix', 'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info', 'warnoptions', 'winver'] >>>
(5)パッケージ
パッケージ (package) は、ドットを付けてモジュールを構造化(まあ、階層化と思ってもいいだろう)する。
(6)関数その他
・関数アノテーション
Annotation(注釈)のこと