masakunの日記: 第5章 関数(すっきりPython 193~242頁) 2
関数は作れる
def masakun():
print('おれは、、、') #処理は字下げして記述
print('(⌒~⌒)')
masakun()
実行結果
おれは、、、
(⌒~⌒)
ただし既存関数の上書きといった名前の衝突はご法度。
ローカル変数と独立性
関数内で準備された変数は、その関数の中でしか読み書きできないというルールがある。これを「ローカル変数の独立性」と言う。
def input_score():
name = '' #関数の中で使う変数
print('{name}の試験結果を入力してください')
name='浅木'
input_score()
name='松田'
input_score()
実行結果
{name}の試験結果を入力してください
{name}の試験結果を入力してください
'浅木'や'松田'は input_score 関数の中に代入されない。
☆☆☆ 引数と戻り値 ☆☆☆
a=[2,3,4,5]
x=len(a)
len関数に引き数(a)を渡す。このやり方をどうやって実装するか。
def input_sco(name): #データを受け取る変数[仮引数]
print(f'{name}の試験結果を入力してください')
input_sco('浅木') #関数に'浅木'を渡す[実引数]
input_sco('松田') #関数に'松田'を渡す
関数を定義する時に(name)と書かれている。これはこの関数が呼び出された時に渡されたデータを name という引数で受け取り、関数内で扱っていくことを表明するもの。
def hello(namae):
print(f'こんにちは{namae}です')
namae = '山田'
print(f'こんにちは{namae}です')
namae = input('What your name?>>')
hello(namae)
print(namae)
実行結果
What your name?>> susuki
こんにちはsusukiです
こんにちは山田です
susuki
3行目の「こんにちは山田です」は関数内で定義されたものが表示されている。
def calc_average(scores):
avg = sum(scores) / len(scores)
print('平均点は{}です'.format(avg))
引数には数値や文字列だけでなく、コレクションも引き渡すことができる。
def input_scores(name):
print(f'{name}さんの試験結果を入力してください')
network = int(input('ネットワークは?'))
database = int(input('データベースは?'))
security = int(input('セキュリティは?'))
scores = [network, database, security]
def calc_average(scores):
avg = sum(scores) / len(scores)
print(f'平均点は{avg}点です')
input_scores('浅木')
calc_average(scores)
実行結果
浅木さんの試験結果を入力してください
ネットワークは? 60
データベースは? 55
セキュリティは? 80
(略)
---> 11 calc_average(scores)
NameError: name 'scores' is not defined
本当は input_scores 関数で入力した scores を、calc_average に渡したかったが、
実引数の calc_average(scores) の scores が空っぽなのでエラーになってしまう。
そこで戻り値を指定する。
def input_scores(name):
print(f'{name}さんの試験結果を入力してください')
network = int(input('ネットワークは?'))
database = int(input('データベースは?'))
security = int(input('セキュリティは?'))
scores = [network, database, security]
return scores #戻り値を指定
def calc_average(scores):
avg = sum(scores) / len(scores)
print(f'平均点は{avg}点です')
xxx=[]
xxx = input_scores('浅木')
calc_average(xxx)
引数5 ⇒ 円の面積を求める関数(半径×半径×3.14)⇒ 戻り値78.5
引数は複数渡すことができるが、戻り値はひとつのみ。とはいえリストやディクショナリといったコレクションを戻り値として渡すことが可能。
☆☆☆ 関数の応用テクニック ☆☆☆
def plus_and_minus(a,b):
return a + b , a - b
next, prev = plus_and_minus(1978, 1)
和と差の二つの値が戻り値のように見えるが、実際は要素数2のタプル。そして次の行で返ってきたタプルを「アンパック代入」しているだけ(すっきり1章52頁)
name , age = '麻木', 24
でも「暗黙のタプルによる複数の戻り値」という見出しつけてるけど、戻り値にコレクション指定できるのだから言わずもがなじゃん。
〇デフォルト引数
def 関数名(仮引数名 = デフォルト値, …):
処理
return 戻り値
def func(x,y,z=10): #z=10 がデフォルト引数
print(x+y+z)
func(10,20)
実行結果
40
ある仮引数に指定される値が概ね想定される場合、関数内にデフォルト値(デフォルト引数)を持たせることができる。関数呼び出しで実引数が指定されない場合、デフォルト値が指定されたものとみなされる(223頁)。
ただし複数の引数が存在する場合、デフォルト引数が指定された仮引数より後ろに、デフォルト引数がない仮引数を定義することができない制約がある。
〇名前付引数(引数はとりあえず2つ覚えておけば桶)
関数名(仮引数名1 = 実引数1, 仮引数名2 = 実引数2,…)
def func(x,y,z):
print(f'x={x},y={y},z={z}')
print(x+y+z)
func(z=9,y=7,x=8) #名前付き引数
実行結果
x=8,y=7,z=9
24
関数にはキーワード引数も使える。「キーワード=値」となっていて、記述した順序にかかわらず指定した仮引数に渡される。
〇グローバル変数
global 変数名
関数内のローカル変数はグローバル変数を上書きできない
name = 'マツダ' #グローバル変数
def change_name():
name = '浅木' #ローカル変数
def hello():
print('こんにちは'+ name + 'さん')
change_name()
hello()
実行結果
こんにちはマツダさん
マツダを浅木に変えるには global 変数だよと宣言しちゃえばよし
name = 'マツダ' #グローバル変数
def change_name():
global name
name = '浅木' #グローバル変数
def hello():
print('こんにちは'+ name + 'さん')
change_name()
hello()
実行結果
こんにちは浅木さん
関数は外の世界から独立していて、引数や戻り値を使わなければやりとりできない関数のお約束があるが、それを打ち破るのがグローバル変数。
ただし大きな開発で、個人がグローバル変数を乱用するとバグの温床となる。
なので非推奨。
閏年を判定する練習問題の答え:
def is_leapyear(year):
return (year % 400 == 0 or (year % 4 == 0 and year % 100 != 0))
ac = int(input('西暦年を入力してください'))
if is_leapyear(ac): #閏年になる条件は True なので。
print(f'西暦 {ac} 年は閏年だよ')
else:
print(f'西暦 {ac} 年はちがうよ')
闇の魔術は教えないのか (スコア:0)
関数内関数とかnon localとかglobalとかあれとかそれとかで愉快なパズルができるのに…
Re:闇の魔術は教えないのか (スコア:1)
独立性の破れのセクション(230頁)にあるこれのことかな?
モデレータは基本役立たずなの気にしてないよ