python 11:関数
9134 ワード
大規模なプログラムを作成する必要がある場合は、他の場所で呼び出すためにコードを書くか、プログラムの同じ論理を抽出する必要があります.この場合、関数を使用する必要があります.しかし、関数はこれらの機能を提供するだけでなく、関数を使用することでコードの理解を容易にすることができます.
関数の定義
次のコードは、Fibonacci数列を計算する関数fibを定義します.
関数の最初の行は記述的な文字列であってもよく、オプションであれば、関数の一部として格納され、ドキュメント文字列となります.ドキュメント文字列を使用して、オンラインまたは印刷されたドキュメントを自動的に生成するツールや、次の方法でアクセスできます.
パラメータのデフォルト値の指定
関数パラメータのデフォルト値を指定すると、次のように、関数を呼び出すときにより少ないパラメータを指定できます.
1)必須パラメータのみを指定します.
警告:デフォルト値は1回のみ付与されますが、デフォルト値が可変オブジェクト(list、辞書、または可変クラスのインスタンスなど)の場合、問題が発生する可能性があります.次の例を参照して、入力された値を集計します.
キーワードパラメータ
関数は、kwarg=valueの形式でキーワードパラメータを使用して呼び出すことができます.次に例を示します.
可変長パラメータ
関数は可変長パラメータをサポートし、入力されたパラメータは1つのメタグループにパッケージされ、可変長パラメータの前に0つ以上のパラメータが提供されます.
リストとメタグループのパッケージ解除
前に'*'と'**'を使用して入力パラメータをメタグループと辞書にパッケージ化しましたが、パラメータがlistまたはメタグループの場合、パラメータ入力関数としてどのように使用しますか?'*'と'**'を使用して、パッケージを解くことができます.次の例を見てください.
Lambda式
Lambdaキーワードを使用すると、次の関数が2つのパラメータの和を返すなど、小さな匿名の関数を作成できます.
関数コメント
関数コメントは、ユーザー定義関数に関する任意の情報を含むオプションです.python自体も標準ライブラリも関数注釈を使用しません.ここでは関数注釈の構文を示します.コメントは関数の__に格納されます.annotations__プロパティでは、パラメータコメントはパラメータの後ろにコロン定義を付けて、式に従います.構文->定義によるコメントを返します.次に例を示します.
アクティブドメイン
pythonの変数は辞書に格納され、「名前->値」として格納されます.組み込まれたvars関数は、この辞書を返します.
pythonでは、globals関数を使用してグローバル変数値を取得する方法があります.この関数の近親はvarsです.たとえば、次のようにします.
関数の定義
次のコードは、Fibonacci数列を計算する関数fibを定義します.
>>> def fib(n):
"""Print a Fibonacci series up to n."""
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
>>> fib(200)
0 1 1 2 3 5 8 13 21 34 55 89 144
は、まずキーワードdefであり、関数名とパラメータのリストに続く.次の行から関数の本体になり、インデントする必要があります.関数の最初の行は記述的な文字列であってもよく、オプションであれば、関数の一部として格納され、ドキュメント文字列となります.ドキュメント文字列を使用して、オンラインまたは印刷されたドキュメントを自動的に生成するツールや、次の方法でアクセスできます.
>>> fib.__doc__
'Print a Fibonacci series up to n.'
またはhelp関数を使用します.>>> help(fib)
Help on function fib in module __main__:
fib(n)
Print a Fibonacci series up to n.
関数はreturnを使用して値を返します.たとえば、上のfib関数の結果シーケンスを返します.>>> def fib2(n):
"""Return a list containing the Fibonacci series up to n."""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
>>> f100 = fib2(100)
>>> f100
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
関数にreturn文がない場合は、次のようなNoneを返します.>>> f100 = fib(100)
0 1 1 2 3 5 8 13 21 34 55 89
>>> print(f100)
None
では、pythonの関数の詳細について説明します.パラメータのデフォルト値の指定
関数パラメータのデフォルト値を指定すると、次のように、関数を呼び出すときにより少ないパラメータを指定できます.
>>> def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no', 'nop', 'nope'):
return False
retries = retries - 1
if retries < 0:
raise OSError('uncooperative user')
print(complaint)
この関数は、次の方法で呼び出すことができます.1)必須パラメータのみを指定します.
>>> ask_ok('Do you really want to quit?')
Do you really want to quit?y
True
)オプションのパラメータの1つに、>>> ask_ok('OK to overwrite the file?', 2)
OK to overwrite the file?n
False
)すべてのパラメータが与えられます.>>> ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
OK to overwrite the file?n
False
関数のデフォルト値は、定義された瞬間に決定されます.たとえば、次のようになります.>>> i = 5
>>> def f(arg=i):
print(arg)
>>> i = 6
>>> f()
5
fを定義するときiの値は5であるため、f()を呼び出すと常に5が印刷される.警告:デフォルト値は1回のみ付与されますが、デフォルト値が可変オブジェクト(list、辞書、または可変クラスのインスタンスなど)の場合、問題が発生する可能性があります.次の例を参照して、入力された値を集計します.
>>> def f(a, L=[]):
L.append(a)
return L
>>> print(f(1))
[1]
>>> print(f(2))
[1, 2]
>>> print(f(3))
[1, 2, 3]
複数の呼び出し間でデフォルト値を共有したくない場合は、次のことができます.>>> def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
キーワードパラメータ
関数は、kwarg=valueの形式でキーワードパラメータを使用して呼び出すことができます.次に例を示します.
>>> def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.")
print("-- Lovely plumage, the", type)
print("-- It's", state, "!")
parrotは、強制パラメータと3つのオプションパラメータを指定します.parrotは、次の形式で呼び出すことができます.parrot(1000)
parrot(voltage=1000)
parrot(voltage=1000000, action='VOOOOOM')
parrot(action='VOOOOOM', voltage=1000000)
parrot('a million', 'bereft of life', 'jump')
parrot('a thousand', state='pushing up the daisies')
次の呼び出し方法が無効であることに注意してください.parrot()
parrot(voltage=5.0, 'dead')
parrot(110, voltage=220)
parrot(actor='John Cleese')
可変長パラメータ
関数は可変長パラメータをサポートし、入力されたパラメータは1つのメタグループにパッケージされ、可変長パラメータの前に0つ以上のパラメータが提供されます.
>>> def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
*argsは、任意のパラメータを入力できることを示します.通常、可変パラメータは、後続の入力パラメータがすべて含まれるため、パラメータリストの最後に配置されます.任意の可変パラメータの後ろのパラメータは、キーワードパラメータとして使用する必要があります.具体的な例を見てみましょう.>>> def concat(*args, sep="/"):
return sep.join(args)
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
'*'、pythonは'**'をサポートします.'*'.入力を表すパラメータは辞書です.次の例を見てください.>>> def print_params(**params):
print(params)
>>> print_params(x=1,y=2,z=3)
{'z': 3, 'x': 1, 'y': 2}
は、paramsを辞書として印刷する.総合的な例を見てみましょう>>> def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
keys = sorted(keywords.keys())
for kw in keys:
print(kw, ":", keywords[kw])
>>> cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
リストとメタグループのパッケージ解除
前に'*'と'**'を使用して入力パラメータをメタグループと辞書にパッケージ化しましたが、パラメータがlistまたはメタグループの場合、パラメータ入力関数としてどのように使用しますか?'*'と'**'を使用して、パッケージを解くことができます.次の例を見てください.
>>> args = [3, 6]
>>> list(range(*args))
[3, 4, 5]
同様に、辞書はキーワードパラメータとして使用できます.'**'オペレータを使用します.>>> def parrot(voltage, state='a stiff', action='voom'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.", end=' ')
print("E's", state, "!")
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
Lambda式
Lambdaキーワードを使用すると、次の関数が2つのパラメータの和を返すなど、小さな匿名の関数を作成できます.
lambda a, b: a+b
lambda関数は、文法的に単一の式に制限され、意味的には、通常の関数定義の簡略化された構文にすぎない.ネスト関数定義のように、lambda関数は範囲内の変数を参照します.>>> def make_incrementor(n):
return lambda x: x + n
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
は、Lambda式を使用して関数を返します.次の例では、パラメータとして小さな関数を渡します.>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
関数コメント
関数コメントは、ユーザー定義関数に関する任意の情報を含むオプションです.python自体も標準ライブラリも関数注釈を使用しません.ここでは関数注釈の構文を示します.コメントは関数の__に格納されます.annotations__プロパティでは、パラメータコメントはパラメータの後ろにコロン定義を付けて、式に従います.構文->定義によるコメントを返します.次に例を示します.
>>> def f(ham: 42, eggs: int = 'spam') -> "Nothing to see here":
print("Annotations:", f.__annotations__)
print("Arguments:", ham, eggs)
>>> f('wonderful')
Annotations: {'return': 'Nothing to see here', 'ham': 42, 'eggs': <class 'int'>}
Arguments: wonderful spam
アクティブドメイン
pythonの変数は辞書に格納され、「名前->値」として格納されます.組み込まれたvars関数は、この辞書を返します.
>>> x = 1
>>> scope = vars()
>>> scope['x']
1
という辞書をネーミングスペースまたは役割ドメインと呼びます.各関数呼び出しには、新しい役割ドメインが作成されます.関数内の変数はローカル変数と呼ばれ、パラメータはローカル変数に似ています.pythonでは、globals関数を使用してグローバル変数値を取得する方法があります.この関数の近親はvarsです.たとえば、次のようにします.
>>> def combine(parameter):
print(parameter + globals()['parameter'])
>>> parameter = 'berry'
>>> combine('Shrub')
Shrubberry
は、グローバル変数をバインドする方法も使用できます.>>> x = 1
>>> def change_global():
global x
x = x + 1
>>> change_global()
>>> x
2
しかし、これは混乱を招きやすいので、できるだけしないことをお勧めします.