ホームページ >バックエンド開発 >Python チュートリアル >Python 関数の入門
関数を呼び出すには、1 つのパラメーターを受け取る絶対値関数 abs など、関数の名前とパラメーターを知っている必要があります。
ドキュメントは Python の公式 Web サイトから直接表示できます:
http://docs.python.org/2/library/functions.html#abs
ヘルプを使用して対話型コマンドラインで abs 関数を表示することもできます(abs) ヘルプ情報。 abs abs>> abs>>
関数を呼び出すときに、渡されたパラメーターの数が正しくない場合は TypeError が報告され、Python は次のように明確に通知します: abs() にはパラメーターが 1 つしかありませんが、2 つ指定されています: >> ;> abs(1, 2)トレースバック (最新の呼び出しは最後):
ファイル "
TypeError: abs() は引数を 1 つだけ取ります (2 つ与えられます)
If渡されたパラメーターの数は正しいですが、パラメーターの型が関数で受け入れられない場合、TypeError エラーが報告され、次のエラー メッセージが表示されます: str は間違ったパラメーターの型です:
トレースバック (最新の呼び出しは最後):
ファイル "TypeError: abs() のオペランド タイプが正しくありません: 'str'
比較中関数 cmp(x, y) には 2 つのパラメーターが必要です。 x
-1
1
>>> cmp(3, 3)0
組み込みの共通関数にはデータ型変換関数も含まれていますたとえば、int() 関数は他のデータ型を整数に変換できます。 () 関数は他の型を str に変換します:
'123'
>> str(1.23)'1.23'
関数を作成します。
in Python で関数を定義するには、def ステートメントを使用し、関数名、括弧、括弧内のパラメーター、およびコロン: を記述してから、インデントされたブロックに関数本体を記述し、return ステートメントを使用して関数を返します。関数の戻り値。
if ステートメントが実行されるとき、return が実行されると、関数が実行され、結果が返されます。したがって、条件判定やループ処理により、関数内に非常に複雑なロジックを実装することができます。
return文がない場合、関数実行後に結果が返されますが、結果はNoneとなります。
return none を return と省略することもできます。
複数の値を返す:
関数は複数の値を返すことができますか?答えは「はい」です。
たとえば、ゲームでは、座標、変位、角度を指定して、ある点から別の点に移動する必要があることがよくあります。
# 数学パッケージには、sin() 関数と cos() 関数が用意されています。まずは import で参照します:
import math
def move(x, y, step, angle):nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)return nx, ny
したがって、同時に戻り値を取得できます:
>>> x, y = move(100, 100, 60, math.pi / 6)
>> ;> print x, y
しかし実際には、これは単なる幻想であり、Python 関数は依然として単一の値を返します:
>>> r = move(100, 100, 60, math) .pi / 6)
>>> print r(151.96152422706632, 70.0)
戻り値がタプルであることがわかります。 ただし、構文上、タプルを返すときに括弧は省略でき、複数の変数が同時にタプルを受け取り、位置に応じて対応する値を割り当てることができるため、Pythonの関数は複数の値を返します。実際にはタプルを返しますが、記述したほうが便利です。 再帰関数:
関数内で他の関数を呼び出すことができます。関数がそれ自体を内部的に呼び出す場合、関数は再帰的です。
たとえば、fact(n) という関数で表される階乗 n! = 1 * 2 * 3 * ... * n を計算してみましょう:
def fat(n):
Return n * Fact (n -1)
再帰関数を使用するときは、スタックオーバーフローを防ぐように注意してください。コンピュータでは、関数呼び出しはスタックのデータ構造を通じて実装され、関数呼び出しが開始されるたびにスタック フレームがスタックに追加され、関数が返されるたびにスタック フレームがスタックから減算されます。スタックのサイズは無限ではないため、再帰呼び出しが多すぎるとスタック オーバーフローが発生します。ファクト(10000)を計算してみてください。
関数 move(n, a, b, c) の定義は、b を使用して n 個のディスクを a から c に移動することです。
参考コード:
def move(n, a, b, c):
if n ==1:
print a, '-->', c
return
move(n-1, a, c , b)
print a, '-->', c
move(n-1, b, a, c)
move(4, 'A', 'B', 'C')
再帰呼び出しスタックのオーバーフローを解決する方法は、末尾再帰の最適化です。実際、末尾再帰とループの効果は同じであるため、ループを特別な末尾再帰関数とみなしても問題ありません。
末尾再帰とは、関数が戻るときに関数自体が呼び出され、return ステートメントに式を含めることができないことを意味します。このようにして、コンパイラまたはインタプリタは末尾再帰を最適化し、何度呼び出されても再帰自体が 1 つのスタック フレームのみを占有するようにし、スタック オーバーフローが発生しないようにすることができます。
上記の fat(n) 関数は、n * fat(n - 1) を返すため乗算式を導入しているため、末尾再帰的ではありません。末尾再帰に変更するには、主に各ステップの積を再帰関数に渡すために、もう少しコードが必要です:
def fat(n):
return fat_iter(n, 1)def fat_iter(num, product) :
if num == 1: return product return fat_iter(num - 1, num * product)
return fat_iter(num - 1, num * product) は再帰関数自体、num - 1 と num のみを返すことがわかります。 * 積は関数呼び出しの前に計算され、関数呼び出しには影響しません。
fact(5) に対応する fat_iter(5, 1) の呼び出しは次のとおりです。 > fat_iter (3, 20)
===> fat_iter(2, 60)===> 120
完了するとスタックは増加しないため、何度呼び出してもスタックがオーバーフローすることはありません。
残念ながら、ほとんどのプログラミング言語は末尾再帰に対して最適化されておらず、Python インタプリタも最適化されていないため、上記の fat(n) 関数を末尾再帰に変更してもスタック オーバーフローが発生します。
123
>> > int('123', 8)83
int() 関数の 2 番目のパラメータが渡されない場合、デフォルトは 10 進数 (base=10) です。渡されたパラメータを使用するだけです。
関数のデフォルトのパラメータは、必要なパラメータを渡すだけで呼び出しを簡略化するために使用されていることがわかります。ただし、必要に応じて、追加のパラメータを渡してデフォルトのパラメータ値をオーバーライドできます。
s = 1
while n > 0:n = n - 1
s = s * x return s
正方形の数が最も多く計算されると仮定すると、n > 0 の場合、n のデフォルト値を 2:
def power(x, n=2):
s = 1
n = n-1
パラメータは左から右の順序で照合されるため、デフォルト パラメータは必須パラメータの後にのみ定義できます:
# OK:def fn1(a, b=1, c=2):
pass# Error:def fn2( a=1, b):
pass
まず関数を定義し、リストを渡し、END を追加して返します:
def add_end(L=[]):
L. append('END') return L
普通に呼び出すと良い結果が得られます:
>>> add_end([1, 2, 3])[1, 2, 3, 'END'] >>> add_end( ['x', 'y', 'z'])['x', 'y', 'z', 'END']
デフォルトのパラメータを使用して呼び出すと、最初の結果も正しいです:
>>> add_end()['END']
>>> )['END', 'END ']>>> add_end()['END', 'END', 'END']
多くの初心者は混乱します。デフォルトのパラメータは [] ですが、関数は前回「END」を追加した後のリストを「記憶」しているようです。
その理由は次のように説明されます:
Python 関数が定義されると、デフォルト パラメーター L の値、つまり [] が計算されます。これは、デフォルト パラメーター L もオブジェクト [ を指す変数であるためです。 ] 関数が呼び出されるたびに、L の内容が変更されると、次回呼び出されたときにデフォルトのパラメータの内容が変更され、関数を定義したときの [] ではなくなります。
したがって、デフォルト パラメータを定義するときは、次の 1 つのことに留意する必要があります。デフォルト パラメータは不変オブジェクトを指している必要があります。
上記の例を変更するには、不変オブジェクト None を使用できます:
def add_end(L=None):
if L is None:
L = []
L.append('END') return L
これで、何度呼び出しても問題ありません:
>>> add_end()['END']
なぜ str や None のような不変オブジェクトを設計するのでしょうか?不変オブジェクトが作成されると、オブジェクト内のデータは変更できないため、データの変更によって発生するエラーが減少します。また、オブジェクトは変化しないため、マルチタスク環境でオブジェクトを同時に読み込む際にロックする必要がなく、同時読み込みでも全く問題ありません。プログラムを書くとき、不変オブジェクトを設計できる場合は、不変オブジェクトとして設計するようにしてください。
変数パラメータを定義します:
関数に任意の数のパラメータを受け入れさせたい場合は、変数パラメータを定義できます:
def fn(*args):
print args
variable * パラメータ名の前に 0 個、1 個以上のパラメータを渡すことができます:
>>> fn( 'a')
('a',)
>>> fn('a', 'b')
>>> , 'c')
('a', 'b', 'c')
print('name:', name, 'age:', age, 'other:', kw)
function person (必須以外)パラメータ名と年齢に加えて、キーワードパラメータ kw も受け入れます。この関数を呼び出すときは、必須パラメータのみを渡すことができます:
name: Michael age: 30 other: {}
任意のパラメータを渡すこともできますnumber キーワード パラメーターの数:
name: Bob age: 35 other: {'city': 'Beijing'}>> > person('Adam', 45, 性別='M', job='エンジニア')
名前: アダム 年齢: 45 その他: {'性別': 'M', '職業': 'エンジニア'}
キーワードパラメータは何に使用されますか?関数の機能を拡張できます。たとえば、person 関数では、name と age の 2 つのパラメータを受け取ることが保証されていますが、呼び出し元がさらに多くのパラメータを提供したい場合は、それらを受け取ることもできます。ユーザー登録機能を実行していると想像してください。ユーザー名と年齢は必須ですが、それ以外はすべてオプションです。この機能を定義するには、キーワード パラメーターを使用します。
if 'city' in kw: # あります市のパラメータ
pass if 'job' in kw:# ジョブパラメータがある
pass
proprint ('name:', name, 'age:', Age, 'Other:', kw)
ただし呼び出し元キーワード パラメーター:
制限したい場合キーワード パラメータの名前。名前付きのキーワード パラメータだけを使用できます。たとえば、キーワード パラメータとして受け取れるのは都市とジョブのみです。この方法で定義された関数は次のとおりです:
print(name, age, city, job)
はキーワードパラメータ **kw, とは異なります。名前付きキーワード パラメータには特別な区切り文字 * が必要で、* に続くパラメータは名前付きキーワード パラメータとして扱われます。
呼び出しメソッドは次のとおりです:
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24北京エンジニア
名前付きキーワードパラメータを渡す必要がありますパラメータ name には、位置パラメータとは異なります。パラメーター名が渡されない場合、呼び出しはエラーを報告します:
>>> person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most last call last):
File
呼び出し時にパラメーター名 city と job が欠落しているため、Python インタープリターはこれら 4 つを扱いますパラメータは位置パラメータとして使用できますが、 person() 関数は 2 つの位置パラメータのみを受け入れます。
名前付きキーワード引数にはデフォルト値を指定できるため、呼び出しが簡素化されます:
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
キーワード パラメータ city にはデフォルト値があり、呼び出し時に city パラメータを渡す必要はありません:
>>> person('Jack', 24, job='Engineer')
Jack 24 北京エンジニア
使用キーワード パラメータに名前を付けるときは、* がパラメータではなく特別な区切り文字であることに特に注意してください。 * が欠落している場合、Python インタプリタは位置引数と名前付きキーワード引数を認識しません:
def person(name, age, city, job):
#* が欠落している場合、都市と職業は位置引数として扱われます
pass
パラメーターの組み合わせ:
Python で関数を定義する場合、必須パラメーター、デフォルト パラメーター、変数パラメーター、キーワード パラメーター、および名前付きキーワード パラメーターを組み合わせて使用できます。ただし、変数パラメーターは名前付きパラメーターと組み合わせることはできません。 Word パラメータミックス。ただし、パラメータ定義の順序は、必須パラメータ、デフォルト パラメータ、可変長パラメータ/名前付きキーワード パラメータ、キーワード パラメータである必要があることに注意してください。
たとえば、上記のパラメータを含む関数を定義します:
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b , 'c =', c, 'args =', args, 'kw =', kw)def f2(a, b, c=0, *, d, **kw):
print('a =' , a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
関数が呼び出されると、Python インタープリターはパラメーターに従って自動的にそれを解釈します位置と名前が渡されます。
>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}>>> f1(1, 2, c=3) = 1 b = 2 c = 3 args = () kw = {}>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}>>>f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 引数= ('a', 'b') kw = {'x': 99}>f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
a = 1 b = 2 c = 3 引数 = (4,) kw = {'d': 99, 'x': '#'}>>> 引数 = (1, 2, 3)>>> ': 88 , 'x': '#'}>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'したがって、どの関数でも、パラメーターがどのように定義されているかに関係なく、 func(*args, **kw) のような形式で呼び出すことができます。
概要
Python の関数には非常に柔軟なパラメーター形式があり、単純な呼び出しを実装できるだけでなく、非常に複雑なパラメーターを渡すこともできます。
デフォルトパラメータは不変オブジェクトを使用する必要があります。変数オブジェクトの場合、プログラムの実行時にロジックエラーが発生します。
変数パラメーターとキーワード パラメーターを定義する構文に注意してください:
*args は変数パラメーター、args はタプルを受け取ります;
**kw はキーワード パラメーター、kw は辞書を受け取ります。
そして、関数を呼び出すときに変数パラメーターとキーワード パラメーターを渡す方法の構文:
変数パラメーターは func(1, 2, 3) のように直接渡すことも、最初にリストまたはタプルを組み立てることもできます。次に pass * args を渡します: func(*(1, 2, 3));
キーワードパラメータは func(a=1, b=2) で直接渡すことも、最初に dict をアセンブルしてからアセンブルすることもできます**kw Enter: func(**{'a': 1, 'b': 2}) を介して渡します。
*args と **kw の使用は Python のイディオムです。 もちろん、他のパラメーター名も使用できますが、このイディオムを使用するのが最善です。
名前付きキーワード パラメータは、呼び出し元が渡すことができるパラメータ名を制限し、デフォルト値を提供するために使用されます。
名前付きキーワードパラメータを定義するときは、区切り文字 * を忘れずに書いてください。そうしないと、位置パラメータが定義されてしまいます。