python——関数

22128 ワード

1.関数の作成
関数は呼び出すことができます(パラメータがあるか、パラメータがないか)、あるアクションを実行し、値を返します.一般に、組み込まれたcallable関数は、関数が呼び出されるかどうかを判断するために使用することができる.
1 >>> import math
2 >>> x = 1
3 >>> y = math.sqrt
4 >>> callable(x)
5 False
6 >>> callable(y)
7 True

注意:callable関数はpython 3にあります.0では使用できません.式hasattr(func,_call_)を使用する必要があります.代わりに.
関数を用いてフィボナッチ数列を実現する
1 #           
2 def fibs(num):
3     result = [0,1]
4     for i in range(num-2):
5         result.append(result[-2]+result[-1])
6     return result
7 #         
8 result = fibs(10)
9 print(result)

  1.ドキュメント化関数
他の人がこの関数を使うときに理解してもらうために、コメントを付けることができます.もう1つの方法は、文字列を直接書くことです.例は次のとおりです.
  
 1 def fibs(num):
 2     '             '
 3     result = [0,1]
 4     for i in range(num-2):
 5         result.append(result[-2]+result[-1])
 6     return result
 7 #       
 8 print(fibs.__doc__)
 9 
10 -----
11 12 D:\Python27\python.exe D:/pythonwork/test01/function_1.py
13              

  2.真の関数ではない関数
数学的な意味での関数は,常にそのパラメータを計算した後に点を返す.Pythonのいくつかの関数は何も返さない.他の言語では、このような関数にはプロシージャなどの他の名前がある可能性があります.しかしpythonの関数は関数であり、基本的に数学的な意味ではそうではない.
return文がないか、return文があるが、returnの後に値が付いていない関数は値を返さない.
1 >>> def test():
2 ...     print('hello python')
3 ...     #    return            
4 ...     return
5 ...     print('hi python')
6 ...
7 >>> test()
8 hello python
9 >>> x = test()
  hello python
 >>> print(x)
  None

test関数は実際に値「None」を返します
注意:デフォルトの行為に惑わされてはいけない.if文内で値を返す場合は、他のブランチにも他の戻り値があることを確認します.これにより、呼び出し元がシーケンスを期待している場合、Noneは意図的に返されません.
2.パラメータ魔法
  1.単純にパラメータと実パラメータを区別する
pythonでdef文に書かれた関数名の後ろに書かれた変数は、通常、関数のパラメータと呼ばれ、関数を呼び出すときに提供される値は実パラメータ、またはパラメータと呼ばれます.
  2.パラメータを変更できますか?
関数内でパラメータに値を割り当てると、外部の変数の値には影響しません.
1 >>> def try_to_change(n):
2 ...     n = 'Mr.Gumby'
3 ...
4 >>> name = 'Mr.Entity'
5 >>> try_to_change(name)
6 >>> name
7 'Mr.Entity'
8 >>>

分かりやすいように、関数シミュレーションをしなくてもいいです.
1 >>> name = 'Mr.Entity'
2 >>> n = name #              
3 >>> n = 'Mr.Gumby' #        
4 >>> name
5 'Mr.Entity'

注意:パラメータはローカル役割ドメイン(local scope)に格納されます.
リストなどの可変データ構造をパラメータとして使用する場合、次のことが起こります.
1 >>> def change(n):
2 ...     n[0] = 'Mr.Gumby'
3 ...
4 >>> names = ['Mr.G','Mr.Thing']
5 >>> change(names)
6 >>> names
7 ['Mr.Gumby', 'Mr.Thing']
8 >>>

例ではパラメータが変更されていることがわかり,スライス法でコピーをコピーしてからコピーを操作できるという問題を解決した.これで元のデータには影響しません.
  3.パラメータを変更する理由
関数を使用してデータ構造(辞書やリストなど)を変更することは、プログラムを抽象化する良い方法です.
名前を格納し、名前、中間名、または姓で連絡先を照会できるプログラムを作成する必要があるとします.次のデータ構造を使用できます.
1 storage = {}
2 storage['frist'] = {}
3 storage['middle'] = {}
4 storage['last'] = {}

storageというデータ構造は、3つのキー「first」、「middle」、「last」を持つ辞書です.各キーの下に辞書が格納されます.辞書では、名前(名前、中間名、または姓)をキーとして使用し、連絡先リストを値として挿入できます.たとえば、英語の名前をこのデータに追加するには、次のようにします.
 1 me = 'Magnus Lie Hetland'
 2 storage['first']['Magnus'] = [me]
 3 storage['first']['middle'] = [me]
 4 storage['first']['last'] = [me]
 5 print(storage['first']['Magnus'])
 6 print(storage['first']['middle'])
 7 print(storage['first']['last'])
 8 
 9 -------
10 11 D:\Python27\python.exe D:/pythonwork/test01/function_1.py
12 ['Magnus Lie Hetland']
13 ['Magnus Lie Hetland']
14 ['Magnus Lie Hetland']

リストに人名を追加する手順は少し退屈で、特に多くの人名を追加する場合です.コードは次のとおりです.
 1 my_sister = 'Anne Lie Hetland'
 2 storage['first'].setdefault('Anne', []).append(my_sister)
 3 storage['middle'].setdefault('Lie', []).append(my_sister)
 4 storage['last'].setdefault('Hetland', []).append(my_sister)
 5 print(storage['middle']['Lie'])
 6 print(storage['first']['Anne'])
 7 
 8 ----------
 9 10 D:\Python27\python.exe D:/pythonwork/test01/function_1.py
11 ['Magnus Lie Hetland', 'Anne Lie Hetland']
12 ['Anne Lie Hetland']

大きなプログラムを書いてリストを更新すると、プログラムがすぐに肥大化するのは明らかです.
どのように解決するのか、抽象的に使います.抽象的なポイントは、更新時の煩雑な細部を隠し、関数でこの過程を実現することです.
検索ユーザー名を追加するプログラムを実装します.コードは次のとおりです.
 1 #           
 2 def init(data):
 3     data['first'] = {}
 4     data['middle'] = {}
 5     data['last'] = {}
 6 
 7 #       
 8 def lookup(data, label, name):
 9     return data[label].get(name)
10 
11 #           
12 def store(data, full_name):                #     data full_name      ,                    。
13     names = full_name.split()              #     full_name,      names   
14     if len(names) == 2:                    #   names    2,              
15         names.insert(1, '')
16     labels = ('first', 'middle', 'last')
17     for label, name in zip(labels, names): #   zip         ,    (label,name) ,    
18         people = lookup(data, label, name) #       ,         ,      
19         if people:
20             people.append(full_name)
21         else:
22             data[label][name] = [full_name]
23 
24 #####################################   #########################################
25 MyNames = {}
26 #          
27 init(MyNames)
28 #       
29 store(MyNames, 'Naguns Lie Hetland')
30 store(MyNames, 'Anne Lie Hetland')
31 store(MyNames, 'MyNames, Robin Hood')
32 #       
33 name = lookup(MyNames, 'middle', 'Lie')
34 print(name)

  4.パラメータが可変であれば
pythonでは、関数はパラメータオブジェクト自体しか変更できません.しかし、もしあなたのパラメータが可変でなければ(例えば数字)、どうすればいいですか?
すみません、仕方がありません.
        1            
1
>>> def inc(x): return x+1 2 ... 3 >>> inc(10) 4 11 5 >>> x 6 >>> foo = inc(10) 7 >>> foo 8 11
, , :
9 >>> def inc_2(x): x[0] = x[0] + 1 10 ... 11 >>> foo = inc_2(10) 12 >>> foo = inc_2([10]) 13 >>> foo 14 >>> foo = [10] 15 >>> inc_2(foo) 16 >>> foo 17 [11] 18 >>>

  
  5.キーワードパラメータとデフォルト
これまで私たちが使用してきたパラメータは位置パラメータと呼ばれています.彼らの位置は重要で、実際には彼らの名前よりも重要です.
次の例を示します.
 1 def hello_1(greeting, name):
 2     print('%s,%s!' % (greeting, name))
 3 
 4 
 5 def hello_2(name, greeting):
 6     print('%s,%s!' % (name, greeting))
 7 
 8 
 9 hello_1('hello', 'python')
10 
11 hello_2('hello', 'python')
12 
13 -----------------
14   :(             )
15 D:\Python27\python.exe D:/pythonwork/test01/function_2.py
16 hello,python!
17 hello,python!

パラメータの順序は覚えにくいので、簡単にするためにパラメータの名前を指定できます.
def hello_1(greeting='hello', name='python'):
print('%s,s%'%(greeting, name))

#
#

このようなパラメータ名を用いて提供されるパラメータをキーワードパラメータと呼ぶ.彼の主な役割は各パラメータの役割を明確にすることにある.エラーパラメータの呼び出しを回避します.
キーワードパラメータが一番すごいのは、関数でパラメータにデフォルト値を指定できることです.
1 >>> def hello_3(greeting='Hello', name='python'):
2 ...     print('%s,%s!'%(greeting, name))
3 ...
4 >>> hello_3()
5 Hello,python!

  
  6.収集パラメータ
次の書き方では、関数に複数のパラメータを指定できます.
  def print_params(*params):
    print(params)
「*」の意味は「残りの位置パラメータを収集する」ということです.収集のための要素が提供されていない場合、paramsは空の元祖です.
では、キーワードパラメータを処理できますか?次のコードを参照してください.
1 >>> print_params_2('Hmm...', something=42)
2 Traceback (most recent call last):
3   File "<stdin>", line 1, in <module>
4 NameError: name 'print_params_2' is not defined
5 >>>

明らかにだめなので、キーワードパラメータの「収集」を処理する別の方法が必要です.これは「**」を使う必要があります.
事例は以下の通りである.
1 >>> def print_params_3(**params):
2 ...     print(params)
3 ...
4 >>> print_params_3(x=1,y=2,z=3)
5 {'x': 1, 'z': 3, 'y': 2}
6 >>>

テストは実行可能であることを証明します.後悔したのは辞書で、メタグループではありません.
では、一緒に置いてもいいですか?
>>> def print_params_4(x,y,z=3,*pospar, **keypar):
...     print(x,y,z)
...     print(pospar)
...     print(keypar)
...
>>> print_params_4(1,2,3,4,5,foo=1,bar=2)
1 2 3
(4, 5)
{'foo': 1, 'bar': 2}

以前に複数の名前を同時に格納する方法についての質問に戻ります.ソリューションは次のとおりです.
 1 #           
 2 def store(data, *full_names):                  #   “*full_names”    ,          。
 3     for full_name in full_names:               #     data full_name      ,                    。
 4         names = full_name.split()              #     full_name,      names   
 5         if len(names) == 2:                    #   names    2,              
 6             names.insert(1, '')
 7         labels = ('first', 'middle', 'last')
 8         for label, name in zip(labels, names):  #   zip         ,    (label,name) ,    
 9             people = lookup(data, label, name)  #       ,         ,      
10             if people:
11                 people.append(full_name)
12             else:
13                 data[label][name] = [full_name]

  
  7.パラメータ収集の逆プロセス
1 >>> params = {'name':'Sir Robin','greeting':'Well met'}
2 >>> hello_3(**params)
3 Well met,Sir Robin!
4 >>>

関数を定義または呼び出すときにアスタリスク(またはダブルアスタリスク)を使用すると、メタグループまたは辞書のみが渡されます.
アスタリスクは、不定数のパラメータを使用できる関数を定義したり、辞書やシーケンスを分割したりするときにのみ使用できます.
ヒント:
パッチオペレータを使用してパラメータを「渡す」ことは、パラメータの個数などの問題に関心を持たなくても便利です.たとえば、次のような問題があります.
1 def foo(x, y, z, m=0, n=0):
2     print(x, y, z, m, n)
3 
4 
5 def call_foo(*args, **kwds):
6     print('Calling foo!')
7     foo(*args, **kwds)

  
  8.使用パラメータの例:
 1 def story(**kwds):
 2     return 'Once upon a time, there was a %(job)s called %(name)s.' % kwds
 3 
 4 
 5 def power(x, y, *others):
 6     #      
 7     if others:
 8         print('Received redundant parameters:', others)
 9     return pow(x, y)
10 
11 
12 def interval(start, stop=None, step=1):  # start   , stop   , step  
13     'Imitates range() for step >0 '      #      
14     if stop is None:                     #      stop   ...
15         start, stop = 0, start           #     
16     result = []                          #     
17     i = start                            #     
18     while i < stop:                      #      stop   
19         result.append(i)                 #       result 
20         i += step                        #  step    i
21     return result                        #           

 
まとめ:
  • 抽象:抽象は余分な細部を隠す芸術である.処理の詳細を定義する関数は、プログラムをより抽象的にすることができます.
  • 関数定義:関数はdef文で定義されます.彼らは文からなるブロックで、「外部世界」から値(パラメータ)を取得したり、演算結果として1つ以上の値を返したりすることができます.
  • パラメータ:関数は、パラメータから必要な情報、すなわち、関数呼び出し時に設定された変数を得る.Pythonには、位置パラメータとキーワードパラメータの2種類があります.パラメータは、デフォルト値が指定されている場合にオプションです.

  •