Pythonメモ : 関数
関数を呼び出すだけでもある程度の関数の知識が必要。関数の定義、引数、戻り値、引数のデフォルト値、キーワード引数。
関数の定義
defを使って定義。
def 関数名():
処理内容(インデントに注意)
このインデントした処理をする範囲を関数ブロックという。
if文、for文はさらにインデントしてifブロック内やforブロック内に処理内容を記述する
インデントは半角スペース4つ分(Tabキー1回分)処理のまとまりごとにインデントを揃える。関数だけでなくif文for文なども同じ。
定義された関数はそれより下の位置から呼び出すことができる。
関数名()
オブジェクト名の衝突による上書き
では定義したものを消せば?となるけどメモリの中には残っているのか定義したものを消しても消えなかった。delでキッカリ消さないとダメみたい(´・ω・`)変数関数リストなどオブジェクト全体で名前を付ける時は注意が必要です。
関数名のルール
- 予約語(for ifなど)は使えない。(エディタに打ち込むとき色が変わる単語は大抵使えない)
- 先頭が数字はNG
- 先頭が __アンダースコア2つはNG(コンストラクタに使われるため予約されている)
- 小文字で始まるのが望ましい。
- 動詞、動詞_目的語がわかりやすい。
- 大文字と小文字は区別される
- 使用済みの変数名、関数名と同じ名称の関数名はNG(上書されてしまう)
- 複数の単語をつなげる時はスネークケースが推奨されている。例:members_no
引数
def 関数名(仮引数):
関数名(実引数)で関数を呼び出して引数を仮引数に渡す。
def 関数名(仮引数1,仮引数2,仮引数3,...): 複数の仮引数の設置はカンマで区切る。左から順番に処理される。
関数名(実引数1,実引数2,実引数3,...)で関数を呼び出して引数を仮引数に渡す。複数の引数を渡す時にはカンマで区切る。左から順に渡される。仮引数と引数の数が一致していないとエラーになる。
渡す値(オブジェクト)が実引数で受け取る側が仮引数。どちらも総称として引数と呼ばれている。
戻り値
ざっくりいうと戻り値は渡した引数が関数によって処理されてその値をreturnで引数へ戻すこと。
return 返す値 returnの後ろの値が戻される。(returnの戻り値は整数、文字列、コレクションなどのオブジェクトを1つだけ戻す)
returnは終了も兼ねているのでこれより後の記述は無視される。
def cal_sum(x,y):#仮引数に引数2,3が渡され
print(x+y)#これは反映される
return x+y#x+yの計算結果が引数へ戻される
print(x+y)#これは無視される
print(cal_sum(2,3)*5)#(2,3)は戻された結果の値になり5*5となる。
'''実行結果 5
25 '''
def cal_mul(x,y):#仮引数に20,40が渡される。
mul=x*y#渡された20と40を掛けてmulに代入
return mul#変数mulに入っている値800が戻される
x,y=20,40
ans=cal_mul(x,y)#(x,y)は戻された値800になる。
print("掛け算の答えは{}です。".format(ans))
#実行結果:掛け算の答えは800です
#上の関数を使って配列の要素のペアで掛け算
n=int(input())#配列の要素数
a=[int(input())for _ in range(n)]#数値のリスト
for i in range(n):
for j in range(i):
print(cal_mul(a[i],a[j]))
'''5
3
4
5
6
7
12
15
20
18
24
30
21
28
35
42
'''
#returnの戻り値は常に1つ
def cal_min(x,y):
a=x+y
b=x-y
print(a,b)
return a,b#二つに見えるがタプルになっている。
print(cal_min(8,10))#返ってきたアンパックの値がアンパック代入されている。
#実行結果18 -2 (18, -2)
引数のデフォルト値
def 関数名(仮引数…,仮引数名=デフォルト値,仮引数名=デフォルト値):
処理
return 戻り値があれば戻り値の設定
普通の仮引数をデフォルト引数より後ろに置くことができない。デフォルト引数の後にデフォルト引数を置くことはできる。
必要な引数だけ渡して他の渡す引数を省略したり出来る。print関数だとendに値を入れなくても自動で改行が入るのはデフォルト値が設定されているため。
def greeting(name,gree="こんにちは"):
print("{}さん{}".format(name,gree))
greeting("Miya","こんばんは")
greeting("Ken")
#Miyaさんこんばんは
#Kenさんこんにちは
def mo(moji,gara="*"):
a=len(moji)
b=gara*a
c="\n"
d=b+c+moji+c+b
return d
print(mo("abcd","+"))
print(mo("efgh"))
'''
++++
abcd
++++
****
efgh
****
'''
キーワード引数
関数を呼び出すときに渡す引数は左から順番に仮引数に左から順番に渡される。渡したい仮引数を指定して引数を渡したいときにキーワード(仮引数の変数名)を指定して引数を渡すことで任意の仮引数に値を渡すことが出来る。この時も仮引数の設定同様キーワード引数の後に普通の引数を置くことはできない。
関数の呼び出し
関数名(引数,仮引数名=引数,仮引数名=引数…)
print関数はprint(*objects,sep=' ',end='\n',file=None,flush=False)となっており普段はobject以外は省略して呼び出しているがキーワード引数のendで末尾を指定したりする。sepは区切り文字の指定。デフォルト値は半角スペースになっている。
#関数の引数は普通にデフォルト引数のやり方と同じ
def mof(gree="こんにちは",name="moonrose",o="今日もいいてんきですね"):
print(gree+" "+name+","+o)
#引数なしだとデフォルト値
mof()
#引数を渡すと左から順に渡されて左から順に代入される。引数なしの所はデフォルト値
mof("hello","Ken")
#引数を任意の仮引数に渡すことができない。
mof("ここはどうしても1番目の引数になる")
#しかしキーワード引数を使えば指定した仮引数に引数を渡すことが出来る。
mof(o="これがキーワード引数の使い方")
#指定した仮引数に渡されるのでどれから先に書いても大丈夫
mof(o="こうやってどの仮引数に引数を渡すか指定します",name="みなさん",)
#キーワード引数の後には普通の引数はおけない
mof("ただし",o="の後には普通の引数はNG",name="キーワード引数")
'''実行結果
こんにちは moonrose,今日もいいてんきですね
hello Ken,今日もいいてんきですね
ここはどうしても1番目の引数になる moonrose,今日もいいてんきですね
こんにちは moonrose,これがキーワード引数の使い方
こんにちは みなさん,こうやってどの仮引数に引数を渡すか指定します
ただし キーワード引数,の後には普通の引数はNG'''
可変長引数
タプル
def 関数名(仮引数,仮引数,*仮引数): 可変長引数は仮引数の変数名の前にアスタリスクを付ける。呼び出し時にn個以上の実引数を指定することが出来る。可変長引数以降に指定した実引数は1つのタプルとして受け取る。可変長引数の実引数が省略された場合は空のタプルをうけとる。可変長引数は末尾の仮引数にしか指定できない。(仮引数、可変長引数、デフォルト引数の順番)
#可変長引数の定義(タプルの仮引数名をargsとする慣習がある)
#引数は1つのタプルとして受け取る
def katyou(*args):
print(args)
#タプルは()を省略できるので()がないがタプルとして渡している
katyou("abc","def","ghi")
#実行結果:('abc', 'def', 'ghi')
li=["aaa","bbb","ccc"]
#リストをそのまま引数にしてもタプルの要素一つとされる。
katyou(li)
#実行結果:(['aaa', 'bbb', 'ccc'],)
#リストを引数にするときはアンパックして渡す。
katyou(*li)
#実行結果:('aaa', 'bbb', 'ccc')
#可変長引数の後に普通の仮引数は置けないがデフォルト引数は置ける。
li2=[20,10,30,40,50]
def katyo(*num,te=":"):
for i in num:
print(i,end=te)
print()
katyo(*li2)
katyo(*li2,te="/")
#実行結果:20:10:30:40:50:
#実行結果:20/10/30/40/50/
辞書
可変長引数をタプルではなくディクショナリを用いることも出来る。仮引数の前にアスタリスクを2つ付ける。
#可変長引数を辞書で受け取る。
#辞書の仮引数名をkwargsとする慣習がある
def dic_test(**kwargs):
return kwargs
newdic=dic_test(kyoko=50,nanami=60,airi=45,mana=55)
print(newdic)
#実行結果:{'keiko': 50, 'nanami': 60, 'airi': 45, 'mana': 55}
def bb(**x):
print(x)
bb(kyoko=50,nanami=60,airi=45,mana=55)
#実行結果:{'keiko': 50, 'nanami': 60, 'airi': 45, 'mana': 55}
#辞書のkeyをキーワード引数として渡す
dp={"sep":"*","end":"+"}
print(10,20,30,**dp)#辞書をアンパックして渡す。
#実行結果:10*20*30+
print()
dp2={"keiko":50,"aiko":60,"miya":45}
def dic_test2(keiko,aiko,miya):
print(keiko,aiko,miya,**dp)
print()
dic_test2(**dp2)
#実行結果:50*60*45+
関数の呼び出し
関数の呼び出しは定義した関数の下からでないと呼び出すことができない。
#関数を呼び出す位置は定義している関数より下でないとエラーになる。
def test1_and_test2(x):
return test1(5)*test2(4)*x
'''個の位置でのtest1_and_test2関数の呼び出しはtest1_and_test2関数は定義済みだが
test1関数とtest2関数は未定義のためエラーになる。'''
print(test1_and_test2(6))
#実行結果:NameError: name 'test1' is not defined
def test2(x):
return x*2
#この位置からならtest2は定義済みなのでエラーにならない。
print(test2(8))
#実行結果:16
#この時点ではtest1は未定義なのでエラーになる
print(test1(2))
#実行結果: NameError: name 'test1' is not defined
def test1(x):
return x*3
'''test1_and_test2関数を定義した位置ではtest1とtest2関数は未定義だが
test1_and_test2関数を呼び出している位置ではtest1とtest2関数は
定義済みなのでエラーにならない。'''
print(test1_and_test2(6))
#実行結果:720
呼び出したい関数名(引数)で呼び出す。この()は関数呼び出し演算子というらしい。()の左側の関数名を呼び出し()内の引数を呼び出し先に渡し呼び出した関数の処理の終了時に返された戻り値に成るという働きがある。戻り値がない場合はNoneが返ってくる。(NoneはNoneType型の値で何もないを表す。)
#return(戻り値)に値を指定しないとNoneを返す。
def test():
return
print(test())
#実行結果:None
'''これはreturn(戻り値)が無いときも同じ。
(return(戻り値)に値を指定しない場合のreturnを省略していることになる'''
def test2():
print("otamesi")
print(test2())
'''実行結果:
otamesi
None'''
def test3(x,y):
return x*y
#()内の引数が戻り値の値になって帰ってきて()内の値が変化する。
print(test3(78,80))
#実行結果:6240
関数の中から関数を呼び出せる。
def test1(x):
print(x+"なので関数内で呼び出し")
test1("print関数も関数")
#実行結果:print関数も関数なので関数内で呼び出し
def test2(x):
return max(x)
f=[100,200,300,101,105,202]
print(test2(f))
#実行結果:300
def test3(x,y):
return set(x+y)
a=["a","b","c"]
b=["a","b","c","d","e"]
#呼び出すときも呼び出す関数をネスト出来る。
print(test3(a, b))
#実行結果:{'d', 'c', 'e', 'b', 'a'}
print(sorted(test3(a,b)))
#実行結果:['a', 'b', 'c', 'd', 'e']
スコープ
スコープは変数の有効範囲。有効範囲が関数ブロック内のみのローカル変数と有効範囲がないグローバル変数がある。
ローカル変数の独立性: 関数ブロック内のみ有効な変数。グローバル変数と同名の変数を関数内で宣言しても別物として扱われる。グローバル変数: 有効範囲がなくどこでも参照できる。関数の中では参照だけ許されていて値の変更はできない。同名のローカル変数がある場合はローカル変数が優先される。関数内でグローバル変数の値を変えるとき、グローバル変数の宣言をするときはglobal 変数名の後に代入式を書く。(関数内でグローバル変数の値の書き換えは推奨されない)関数内でもグローバル変数はどこからでも参照可能になる。
#グローバル変数
a="通常はこれが参照される。"
d="ブロック外の変数はどこからでも参照可"
e="グローバル変数とローカル変数は同名でも別物として扱われるが"
def test1():
#ローカル変数
a="外側と同名の変数を宣言すると関数の中の方を参照する"
b="関数ブロック内の変数は関数ブロックの外からは参照不可"
#関数の中でグローバル変数宣言するときにはglobalをつける
global e
e="global を付けて宣言しなおせば値が上書される。関数の中でグローバル変数宣言"
print(a)
print(b)
print(d)
print(e)
test1()
''' 実行結果:
外側と同名の変数を宣言すると関数の中の方を参照する
関数ブロック内の変数は関数ブロックの外からは参照不可
ブロック外の変数はどこからでも参照可
global を付けて宣言しなおせば値が上書される。関数の中でグローバル変数宣言
'''
print(a+"関数内で同名の変数を宣言しても外側の変数に影響しない")
#実行結果:通常はこれが参照される。関数内で同名の変数を宣言しても外側の変数に影響しない
#外側から関数の中の変数を参照できない。
print(b)
#実行結果:NameError: name 'b' is not defined
print(e)
#実行結果:global を付けて宣言しなおせば値が上書される。関数の中でグローバル変数宣言
内部関数
内部関数は関数の内部に定義する関数で内部関数の有効範囲はその関数の内部のみ。
関数内で何度も行う処理を関数にまとめることでコードの簡略化と修正のしやすさというメリットがある。関数の内部でしか呼びだせないので外から呼び出されたくない処理、外では必要ない処理などを内部関数として利用するなどということができる。
def ex(x):
def tw(y):#内部関数を定義
return y*5
return tw(x)*5#関数内で内部関数を呼び出している。
print(ex(3))
#実行結果:75
#内部関数の有効範囲は関数内のみで外からの参照はできない。
print(tw(5))
#実行結果:NameError: name 'tw' is not defined
Moduleのimport
自作関数の利用
既存のpathの同ディレクトリ内にモジュールを入れる。
sys.pathとpprint関数でpathを表示。表示されたpathの中にモジュールを入れる。
sys.path.appendでモジュールのpathをリストに追加する。
例としてデスクトップにあるモジュールファイルを取り込みたいと思います。最初はデスクトップのpathはないのでimportしようとしてもエラーになります。sys.path.appendでデスクトップのアドレスパスを追加します。追加するときの引数は文字列で\\で区切ります。(/で区切ってもok。)数値が混ざってないときは\だけでもいいのですがフォルダ名が数値だとうまく反映されない場合があるので。それと一覧でも\\で区切られているので同じようにした方がいいのでしょう。リストになっているので追加同様削除もできまますしsys.path.index('C:\\Users\\user')で調べたい要素のindexをしらべたりもできます。
.pthファイルを作成してsite-packagesフォルダに入れる。
eclipseでimport
そうすればワークスペースフォルダ名.プロジェクトフォルダ名.パッケージ名でプロジェクト内のモジュールを取り込めます。
標準ライブラリ(関数)の利用
外部ライブラリ(関数)の利用
インストールされているものリストに追加される。
もう一つのやり方はターミナルを開いてコマンドから。
conda install パッケージ名でエンター
インストールされたら
インストールされているか確認。リストに無い様ならリスタートしてから再度確認する。
install <package>の<package>部分を入れたいパッケージ名にして実行を押す。
インストールが始まりFINISHENDとでれば終了。
パッケージがいっぱい追加されました。Numpyも入っているみたいです。
GUIがなにも入っていない状態なのでそのままだとグラフが表示されません。つづいてPyQt5をインストールします。
コメント
0 件のコメント :
コメントを投稿