Python3 関数

関数とは、整理され、繰り返し使用でき、単一の、または関連する機能を実現するためのコードブロックです。

関数を使うと、アプリケーションのモジュール性とコードの再利用性が向上します。Python には print() のような多くの組み込み関数が用意されていることはすでにご存知でしょう。しかし、自分で関数を作成することもできます。これはユーザー定義関数と呼ばれます。


関数を定義する

自分が望む機能を持つ関数を定義できます。以下は簡単なルールです:

  • 関数コードブロックはdefキーワードで始まり、その後に関数識別子名と丸括弧が続きます。()。
  • 渡されるすべての引数(パラメータ)は丸括弧の中に置く必要があります。丸括弧の中は引数を定義するために使用できます。
  • 関数の最初の文には、オプションでドキュメント文字列(関数の説明を格納する)を使用できます。
  • 関数の内容はコロンで:始まり、インデントされます。
  • return [式]関数を終了し、オプションで呼び出し元に値を返します。式を伴わない return は None を返すことに相当します。


構文

Python で関数を定義するには def キーワードを使用します。一般的な形式は次のとおりです:

def 函数名(参数列表):
    函数体

デフォルトでは、引数値と引数名は関数宣言で定義された順序に従って照合されます。

例

関数を使って「Hello World!」を出力してみましょう:

#!/usr/bin/python3

def hello() :
    print("Hello World!")

hello()

より複雑な応用として、関数に引数変数を渡します:

例(Python 3.0+)

2つの数値を比較し、大きい方を返します:

#!/usr/bin/python3 def max(a, b): if a > b: return a else: return b a = 4 b = 5 print(max(a, b))

上記の例の出力結果:

5

例(Python 3.0+)

面積を計算する関数:

#!/usr/bin/python3 # 面積を計算する関数 def area(width, height): return width * height def print_welcome(name): print("Welcome", name) print_welcome("サンプル") w = 4 h = 5 print("width =", w, " height =", h, " area =", area(w, h))

上記の例の出力結果:

Welcome サンプル
width = 4  height = 5  area = 20

関数呼び出し

関数を定義する:関数に名前を付け、関数に含まれる引数とコードブロックの構造を指定します。

この関数の基本構造が完成したら、別の関数から呼び出して実行することも、Python コマンドプロンプトから直接実行することもできます。

以下の例ではprintme()関数:

例(Python 3.0+)

#!/usr/bin/python3 # 関数を定義する def printme( str ): # 渡された任意の文字列を出力する print (str) return # 関数を呼び出す printme("ユーザー定義関数を呼び出します!") printme("同じ関数を再度呼び出す")

上記の例の出力結果:

ユーザー定義関数を呼び出します!同じ関数をもう一度呼び出します

引数の渡し方

python では、型はオブジェクトに属し、オブジェクトには異なる型の区別があります。変数には型がありません:

a=[1,2,3]

a="サンプル"

上記のコードでは、[1,2,3]は List 型であり、"サンプル"は String 型です。変数 a には型がなく、オブジェクトへの参照(ポインタ)にすぎません。List 型オブジェクトを指すことも、String 型オブジェクトを指すこともできます。

変更可能(mutable)と変更不可能(immutable)オブジェクト

python では、strings、tuples、numbers は変更不可能なオブジェクトであり、list、dict などは変更可能なオブジェクトです。

  • 変更不可能な型:変数に値を代入しa=5その後再代入するa=10ここでは実際には新しい int 値オブジェクト 10 が生成され、a がそれを指すように変更されます。5 は破棄され、a の値を変更するのではなく、a が新たに生成されたことに相当します。

  • 変更可能な型:変数に値を代入しla=[1,2,3,4]その後再代入するla[2]=5これは list la の3番目の要素の値を変更するだけで、la 自体は変更されず、その内部の一部の値だけが変更されます。

python 関数の引数の渡し方:

  • 変更不可能な型:C++ の値渡しに似ています。整数、文字列、タプルなどです。fun(a) のように、渡されるのは a の値だけで、a オブジェクト自体には影響しません。fun(a) の内部で a の値を変更する場合、新しい a オブジェクトが生成されます。

  • 変更可能な型:C++ の参照渡しに似ています。リスト、辞書などです。fun(la) のように、la 自体が渡されるため、変更後は fun の外部の la にも影響します。

python ではすべてがオブジェクトです。厳密には値渡しや参照渡しとは言えません。変更不可能オブジェクトを渡す、変更可能オブジェクトを渡すと言うべきです。

python の変更不可能オブジェクトを渡す例

を通じてid()関数でメモリアドレスの変化を確認します:

例(Python 3.0+)

def change(a): print(id(a)) # 同じオブジェクトを指している a=10 print(id(a)) # 新しいオブジェクト a=1 print(id(a)) change(a)

上記の例の出力結果は次のとおりです:

4379369136
4379369136
4379369424

関数呼び出しの前後で、仮引数と実引数が同じオブジェクト(オブジェクト ID が同じ)を指していることがわかります。関数内部で仮引数を変更すると、仮引数は異なる ID を指すようになります。

変更可能オブジェクトを渡す例

変更可能オブジェクトを関数内で変更すると、その関数を呼び出した側の関数内でも、元の引数が変更されます。例えば:

例(Python 3.0+)

#!/usr/bin/python3 # 変更可能な関数の説明 def changeme( mylist ): "渡されたリストを変更する" mylist.append([1,2,3,4]) print ("関数内での値:", mylist) return # changeme 関数を呼び出す mylist = [10,20,30] changeme( mylist ) print ("関数外での値:", mylist)

関数に渡したオブジェクトと末尾に新しい内容を追加したオブジェクトは同じ参照です。したがって、出力結果は次のとおりです:

函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
函数外取值:  [10, 20, 30, [1, 2, 3, 4]]

引数

以下は、関数を呼び出すときに使用できる正式な引数の型です:

  • 必須引数
  • キーワード引数
  • デフォルト引数
  • 可変長引数

必須引数

必須引数は正しい順序で関数に渡す必要があります。呼び出し時の数は宣言時と同じでなければなりません。

printme() 関数を呼び出すには、1つの引数を渡す必要があります。そうしないと構文エラーが発生します:

例(Python 3.0+)

#!/usr/bin/python3 # 変更可能な関数の説明 def printme( str ): "渡された任意の文字列を出力する" print (str) return # printme 関数を呼び出す。引数がないとエラーになります printme()

上記の例の出力結果:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    printme()
TypeError: printme() missing 1 required positional argument: 'str'

キーワード引数

キーワード引数は関数呼び出しと密接に関係しています。関数呼び出しでは、キーワード引数を使用して渡される引数値を決定します。

キーワード引数を使用すると、関数呼び出し時の引数の順序が宣言時と異なっていても構いません。Python インタープリターが引数名を使って引数値を照合できるからです。

次の例では、printme() 関数を呼び出すときに引数名を使用しています:

例(Python 3.0+)

#!/usr/bin/python3 # 変更可能な関数の説明 def printme( str ): "渡された任意の文字列を出力する" print (str) return # printme 関数を呼び出す printme( str = "初心者向けチュートリアル")

上記の例の出力結果:

初心者向けチュートリアル

次の例では、関数引数の使用が指定された順序を必要としないことを示しています:

例(Python 3.0+)

#!/usr/bin/python3 # 変更可能な関数の説明 def printinfo( name, age ): "渡された任意の文字列を出力する" print ("名前:", name) print ("年齢:", age) return # printinfo 関数を呼び出す printinfo( age=50, name="サンプル" )

上記の例の出力結果:

名字:  サンプル
年龄:  50

デフォルト引数

関数を呼び出すとき、パラメータが渡されない場合は、デフォルトパラメータが使用されます。次の例では、age パラメータが渡されない場合、デフォルト値が使用されます。

例(Python 3.0+)

#!/usr/bin/python3 # 関数の説明を書きます def printinfo( name, age = 35 ): "渡された任意の文字列を出力します" print ("名前:", name) print ("年齢:", age) return # printinfo 関数を呼び出します printinfo( age=50, name="サンプル" ) print ("------------------------") printinfo( name="サンプル" )

上記の例の出力結果:

名字:  サンプル
年龄:  50
------------------------
名字:  サンプル
年龄:  35

可変長引数

関数が当初宣言したときよりも多くのパラメータを処理できる必要があるかもしれません。これらのパラメータは可変長パラメータと呼ばれ、上記の2種類のパラメータとは異なり、宣言時に名前を付けません。基本的な構文は次のとおりです:

def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]

アスタリスクを付けた*パラメータはタプル(tuple)の形式で取り込まれ、名前のないすべての変数パラメータを格納します。

例(Python 3.0+)

#!/usr/bin/python3 # 関数の説明を書きます def printinfo( arg1, *vartuple ): "渡された任意のパラメータを出力します" print ("出力:") print (arg1) print (vartuple) # printinfo 関数を呼び出します printinfo( 70, 60, 50 )

上記の例の出力結果:

输出: 
70
(60, 50)
関数呼び出し時にパラメータが指定されない場合、それは空のタプルになります。名前のない変数を関数に渡さないこともできます。次の例のとおりです:

例(Python 3.0+)

#!/usr/bin/python3 # 関数の説明を書きます def printinfo( arg1, *vartuple ): "渡された任意のパラメータを出力します" print ("出力:") print (arg1) for var in vartuple: print (var) return # printinfo 関数を呼び出します printinfo( 10 ) printinfo( 70, 60, 50 )

上記の例の出力結果:

输出:
10
输出:
70
60
50

もう1つは、パラメータにアスタリスクを2つ付ける方法です。**基本的な構文は次のとおりです:

def functionname([formal_args,] **var_args_dict ):
   "函数_文档字符串"
   function_suite
   return [expression]

アスタリスクを2つ付けた**パラメータは辞書の形式で取り込まれます。

例(Python 3.0+)

#!/usr/bin/python3 # 関数の説明を書きます def printinfo( arg1, **vardict ): "渡された任意のパラメータを出力します" print ("出力:") print (arg1) print (vardict) # printinfo 関数を呼び出します printinfo(1, a=2,b=3)

上記の例の出力結果:

输出: 
1
{'a': 2, 'b': 3}

関数を宣言するとき、パラメータ内のアスタリスク*単独で出現することができます。例:

def f(a,b,*,c):
    return a+b+c

アスタリスクが単独で出現する場合*、アスタリスク*以降のパラメータはキーワードで渡す必要があります:

>>> def f(a,b,*,c):
...     return a+b+c
... 
>>> f(1,2,3)   # 报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
>>>

匿名関数

Python はlambdaを使用して匿名関数を作成します。

いわゆる匿名とは、もはやdefdef 文のような標準的な形式で関数を定義するために使用しないことを意味します。

  • lambdaは単なる式であり、関数本体はdefdef よりもはるかにシンプルです。
  • lambda の本体は式であり、コードブロックではありません。lambda 式に組み込めるのは限られたロジックだけです。
  • lambda 関数は自身の名前空間を持ち、自身のパラメータリストの外側またはグローバル名前空間にあるパラメータにアクセスすることはできません。
  • lambda 関数は1行でしか書けないように見えますが、C または C++ のインライン関数とは異なります。インライン関数の目的は、小さな関数を呼び出すときにスタックメモリを消費せず、関数呼び出しのオーバーヘッドを減らし、コードの実行速度を向上させることです。

構文

lambda 関数の構文は1つの文だけを含みます。次のとおりです:

lambda [arg1 [,arg2,.....argn]]:expression

パラメータ a に 10 を加える設定:

例

x = lambda a : a + 10 print(x(5))

上記の例の出力結果:

15

次の例では、匿名関数が2つのパラメータを設定します:

例(Python 3.0+)

#!/usr/bin/python3 # 関数の説明を書きます sum = lambda arg1, arg2: arg1 + arg2 # sum 関数を呼び出します print ("加算後の値は :", sum( 10, 20 )) print ("加算後の値は :", sum( 20, 20 ))

上記の例の出力結果:

相加后的值为 :  30
相加后的值为 :  40

匿名関数を関数内にカプセル化できます。これにより、同じコードを使用して複数の匿名関数を作成できます。

次の例では、匿名関数を myfunc 関数内にカプセル化し、異なるパラメータを渡すことで異なる匿名関数を作成します:

例

def myfunc(n): return lambda a : a * n mydoubler = myfunc(2) mytripler = myfunc(3) print(mydoubler(11)) print(mytripler(11))

上記の例の出力結果:

22
33

匿名関数の詳細は次も参照してください:Python lambda(匿名関数)


return 文

return [式]文は関数を終了させ、必要に応じて呼び出し元に式を返すために使用されます。値なしの return 文は None を返します。これまでの例では数値を返す方法を説明していませんでした。次の例では return 文の使用法を示します:

例(Python 3.0+)

#!/usr/bin/python3 # 関数の説明を書きます def sum( arg1, arg2 ): # 2つのパラメータの和を返します. total = arg1 + arg2 print ("関数内 :", total) return total # sum 関数を呼び出します total = sum( 10, 20 ) print ("関数外 :", total)

上記の例の出力結果:

函数内 :  30
函数外 :  30

位置専用引数

Python 3.8 では、関数の仮引数が指定された位置引数として使用しなければならず、キーワード引数の形式を使用できないことを示すために、新しい関数仮引数構文 / が追加されました。

次の例では、仮引数 a と b は指定された位置引数として使用する必要があります。c または d は位置仮引数またはキーワード仮引数にできますが、e と f はキーワード仮引数である必要があります:
def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)

次の使用方法は正しいです:

f(10, 20, 30, d=40, e=50, f=60)

次の使用方法はエラーになります:

f(10, b=20, c=30, d=40, e=50, f=60)   # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60)           # e 必须使用关键字参数的形式
その他の拡張