関数について
def
文を用いて関数を作成する
# study7.py
def add(x, y):
print x + y
# test
add( 3, 4 )
上記のstudy7.pyを実行すると、関数addが定義された後にadd(3,4)が実行されて7が出力される。
> python3 study7.py
7
- 関数の戻り値
C言語同様にreturn
で値を返すことができる。returnしてない関数の戻り値を参照するとNoneになる
def add(x, y):
print(x+y)
def add2(x, y):
return x + y
print(add(3,4))
print(add2(5,8))
7 # add関数内のprint
None # add関数の戻り値のprint
13 # add2関数の戻り値のprint
また、戻り値は、カンマ区切りで指定して複数の値をタプルとして返すことができる。呼び出し側も戻り値を複数の変数のカンマ区切りで指定して展開した状態で受けることもできる。
def func4(x,y):
return x**2, y**3
print(func4(3,2)) # (9, 8)
x, y = func4(5,6)
print("%d, %d" % (x, y) ) # 25, 216
- デフォルト引数
C++のデフォルト引数のようなものも定義できる
def add2(x, y=3):
print x + y
add2( 3, 5 ) # 8
add2( 3 ) # 6
- キーワードを指定して引き数を指定する
引数名を直接指定すれば、順番が異なっても問題ない。
def sub(x,y):
print( x - y )
sub(2,1) # 1
sub(x=2,y=1) # 1
sub(y=2,x=1) # -1
- 可変長引数
関数定義時に引数名に*
と**
をつけると可変長引数となり、呼び出し時に任意の数の引数を指定することができる。名前は何でもいいが、慣例的に*args
、**kwargs
が使われるので、素直に従ったほうがいい。
*args
で引数を渡すと、複数の引数がタプルとして入力される。
def func( *args ):
print(args)
func(5,4,3,2,1) #(5,4,3,2,1)
def func2( *hoge ):
print( hoge )
func2(5,4,3,2,1) #(5,4,3,2,1) ※*argsと同じ
**kwargs
をつけると複数のキーワード引数がディクショナリとして受け取られる。
def func3(**kwargs):
print(kwargs)
func3(name="taro", "age"=25) # {'name': 'taro', 'age': 25}
直接呼出しとimport呼出し
2つのpythonスクリプト(study7a.py, study7b.py)があったする。
study7b.pyには、func()
という共通関数を用意し、study7a.pyから呼び出している。study7b.pyのスクリプト内にもスクリプトの最後にfunc()
のテストコードが記載されている。
当然、ほかから呼び出される場合は、テストコードは実行されたくない。こういった場合は、以下のように__name__
を参照して、__main__
かどうかを判定すると良い。
# study7b.py
import sys
print(__name__)
def func(x,y):
return x+y
if __name__=='__main__' :
print("---- test ----")
print(sys.argv)
ret = func(int(sys.argv[1]), int(sys.argv[2]))
print("ret="+str(ret))
上記を直接実行した場合、__name__
は必ず__main__
になるので、テストコードが実行される。
> python3 study7b.py 4 23
__main__
---- test ----
['study7b.py', '4', '23']
ret=27
一方、下のスクリプトのように、ほかのスクリプトからインポートして、関数func()
を実行すると、__name__
は、モジュール名(ファイル名)である"study7b"になるので、テストコードが呼ばれないようになる。
# study7a.py
import study7b as st
ret = st.func(4, 9)
print(ret)
> python3 study7a.py
study7b
13
モジュールとパッケージ
上記のように1つのスクリプトを再利用するようにしたものをモジュールと呼ぶ。使うときにはimport
でスクリプトファイルを指定すると、インクルードされてほかのスクリプトから利用できる。
一方、パッケージというものもある。これは、複数のスクリプトからなる大きな機能を1つのパッケージとして提供するときに使う。呼び出し側は、ファイルではなくディレクトリを指定する。
ただし、パッケージとして機能させる場合には、各ディレクトリ内に__init__.py
という名称のスクリプトを必ず用意する必要がある。ないとエラーになる。この__init__.py
は、モジュールをimportする時の初期化を行ってくれるファイルで、インポートしたときに最初にコールされる。ただ、何もすることがない場合は、空のファイルでも構わない。
パッケージについての学習はまたにする。そういうものがあることだけ覚えておく。