関数

プログラムが大きくなると、同じロジックを複数の場所に書くことになります。関数を使えば、ロジックを一度書いて名前をつけ、どこからでも使えます。一か所で修正すれば、すべての呼び出しが自動的に修正されます。
def greet(name):
return f"Hello, {name}!"
print(greet("太郎")) # "Hello, 太郎!"
print(greet("花子")) # "Hello, 花子!"一度書いて、どこからでも使い、一か所で修正します。
関数の定義
def キーワードで関数定義を始め、その後に名前、括弧、コロン、インデントされた本体が続きます。関数は呼び出されるまで何もしません。def で定義してから、() で名前を呼び出します。
def say_hello():
print("Hello!")
say_hello() # 関数を呼び出すdef name(): と書いて、その下に本体をインデントします。name() で呼び出すまで何もしません。def は準備をするだけです。return を忘れると、関数は静かに None を返します。これで何度も引っかかりました。 パラメータと引数
パラメータは関数が期待する入力です。括弧内にリストアップします。関数を呼び出すとき、渡す値はパラメータに順番に合致します。
def greet(name, greeting):
print(f"{greeting}, {name}!")
greet("太郎", "Hello") # "Hello, 太郎!"
greet("花子", "Hi") # "Hi, 花子!"パラメータは関数定義内の名前です。引数は関数を呼び出すときに実際に渡す値です。実際には、これらの言葉は同じ意味で使われることが多く、区別が重要になるのは主にドキュメントを読むときです。
デフォルト値
パラメータにデフォルト値を与えることができます。呼び出し元がその引数を指定しない場合、デフォルトが使用されます。デフォルト値を持つパラメータは、デフォルト値を持たないパラメータの後に来る必要があります。
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("太郎") # "Hello, 太郎!"
greet("太郎", "Hi") # "Hi, 太郎!"デフォルト値を持つパラメータは、デフォルト値を持たないパラメータの後に来る必要があります。
キーワード引数
関数を呼び出すときに、引数に名前を付けることができます。これにより、特に多くのパラメータを持つ関数で呼び出しが読みやすくなり、任意の順序で引数を渡すことができます。
def describe_player(name, score, level):
print(f"{name} | Score: {score} | Level: {level}")
describe_player("太郎", 87, 5) # 位置指定
describe_player(name="太郎", level=5, score=87) # キーワード、任意の順序
describe_player("太郎", level=5, score=87) # ミックス:位置指定が最初score=87)と、呼び出しが自分自身を説明し、任意の順序で渡せます。1つのルール:位置引数は名前付きのものの前に来る必要があります。多くのパラメータを持つ関数に最適です。 戻り値
return は値を呼び出し元に送り返します。return がない場合、関数は None を返します。return が実行されると、関数は直ちに終了します。そのブロック内の後続コードはスキップされます。
def add(a, b):
return a + b
result = add(3, 4) # result = 7
print(result)return はまた、関数を直ちに終了します。そのブロック内の後続コードは実行されません。
return は関数を呼び出した人に値を返し、関数はそこで停止します。それ以降のコードはスキップされます。return を省略すると `None` が返されます。print は値を表示し、return は使用するためにそれを返します。この違いを感じるのに時間がかかりました。 複数の値を返す
Pythonは複数の値をコンマで区切って返すことができます。呼び出し元は、タプルとしてそれらを受け取り、1行で別の名前に展開することができます。
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([3, 7, 1, 9, 4])
print(low, high) # 1 9low, high = ... 構文は展開です。Pythonは各戻り値を対応する名前に割り当てます。
low, high = min_max(...) で、値ごとに1つの名前を捕捉します。関数が自然に複数の答えを生成するときはいつでも役立ちます。 スコープ
関数内に作成された変数は、その関数内にのみ存在します。外部からそれらを見ることはできません。すべての関数の外部で定義された変数は至るところで見えますが、明示的な宣言なしに関数内からそれらを変更することはできません。
global 行が必要です。それをほぼ望むことはありません。値を渡し、結果を返します。関数はシンプルに追うことができます。 def calculate():
result = 42 # この関数のローカル
return result
calculate()
print(result) # NameError、resultはここに存在しませんcount = 0
def increment():
global count # グローバルを変更したいことを宣言する
count += 1
increment()
print(count) # 1global を使用することは最後の手段であるべきです。コードを推論するのが難しくなります。値を渡し、返すことを優先してください。スコープは、変数と型の章で説明されている割り当てが名前を値にバインドする方法に直接構築されます。
*args と **kwargs
時々、関数が受け取る引数の数は分かりません。*args は任意の数の位置引数をタプルに集めます。**kwargs は任意の数のキーワード引数を辞書に集めます。名前 args と kwargs は慣習です。星が重要です。
def total(*args):
return sum(args)
total(1, 2, 3) # 6
total(1, 2, 3, 4, 5) # 15def display(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
display(name="太郎", score=87, level=5)通常のパラメータと混ぜることができます。通常のパラメータが最初に来ます。
def describe(title, *tags, **metadata):
print(f"{title} | tags: {tags} | meta: {metadata}")
describe("Python intro", "beginner", "python", author="太郎", year=2024)*args は追加の位置引数の任意の数をタプルとしてすくい上げます。**kwargs は追加の名前付きをを辞書としてすくい上げます。言葉 `args` と `kwargs` は慣習に過ぎません。`*` と `**` が本当の仕事をします。いくつのものが来るかを事前に言えないときに役立ちます。 ドキュメント文字列
ドキュメント文字列は、関数の上部にある、その関数がしていることを説明する文字列です。Pythonエディタやツールはそれを使用して、関数呼び出しにホバーするときにヘルプを表示します。三重引用符を使用し、単純な関数の場合は1行を書きます。
def normalise(value, min_val, max_val):
"""Scale a value to the 0-1 range given the known min and max."""
return (value - min_val) / (max_val - min_val)def build_url(base, version, resource, *, secure=True):
"""
Build an API endpoint URL.
Returns a fully-qualified URL string. If secure is False,
the URL will use http instead of https.
"""
scheme = "https" if secure else "http"
base = base.replace("https://", "").replace("http://", "")
return f"{scheme}://{base}/{version}/{resource}"目的が名前と署名から明確でない関数のドキュメント文字列を書きます。
型ヒント
型ヒントにより、関数が期待する型と返す型に注釈を付けることができます。Pythonは実行時にそれらを強制しません。しかし、エディタはそれらを使用して、何かを実行する前にミスを捕捉します。-> はコロンの前に戻り型を指定します。
def greet(name: str, score: int) -> str:
return f"{name} scored {score}"def log(message: str) -> None:
print(f"[LOG] {message}")def top_scores(scores: list[int], n: int) -> list[int]:
return sorted(scores, reverse=True)[:n]型ヒントはオプションですが、複数の場所から呼び出される関数に価値があります。それらは、ツールが検証できるドキュメンテーションです。
値としての関数
Pythonの関数は、文字列や数値のような値です。変数に割り当てたり、他の関数に渡したりできます。これは sorted() が key= 関数を受け入れる方法です。
def double(x):
return x * 2
def apply(func, value):
return func(value)
apply(double, 5) # 10関数を引数として渡すことは sorted()、map()、filter() で絶えず表れます。また、ラムダと内包表記の章でそれを見ます。
実装例
一緒に動作する2つの関数:letter_grade はスコアを文字に変換し、summarise はリスト内のすべてのスコアに対してそれを呼び出します。
def letter_grade(score: int) -> str:
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
else:
return "F"
def summarise(scores: list[int]) -> None:
total = sum(scores)
avg = total / len(scores)
grades = []
for s in scores:
grades.append(letter_grade(s))
print(f"Average: {avg:.1f}")
print(f"Grades: {', '.join(grades)}")
summarise([87, 92, 74, 65, 91])
