Python 3.x入門チュートリアル関数


Python 3関数
関数は、単一の、または関連する機能を実現するためのコードセグメントを再利用するために組織されています.
関数は、アプリケーションのモジュール性とコードの再利用率を向上させることができます.Pythonはprint()のような多くの組み込み関数を提供していることを知っています.しかし、ユーザー定義関数と呼ばれる関数を自分で作成することもできます.
関数の定義
自分が機能したい関数を定義できます.以下は簡単なルールです.
関数コードブロックはdefキーワードで始まり、関数識別子名とカッコ()が続く.
任意の入力パラメータと引数は、カッコの中央に配置する必要があります.カッコの間でパラメータを定義できます.
関数の最初の行の文は、ドキュメント文字列を選択的に使用できます.関数の説明を保存します.
関数の内容はコロンで始まり、インデントされます.
return[式]は関数を終了し、呼び出し元に選択的に値を返します.式を持たないreturnはNoneを返すことに相当します.
パラメータ伝達
pythonでは、タイプはオブジェクトに属し、変数にはタイプがありません.
a=[1,2,3]

a="Runoob"

上記のコードでは、[1,2,3]はListタイプであり、「Runoob」はStringタイプであり、変数aはタイプがなく、彼女は1つのオブジェクトの参照(ポインタ)であり、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ではすべてオブジェクトであり、厳密には値の伝達か参照の伝達かは言えません.可変オブジェクトと可変オブジェクトの伝達と言うべきです.
必須パラメータ
必須パラメータは、関数に正しい順序で入力する必要があります.呼び出し時の数は、宣言時と同じでなければなりません.
printme()関数を呼び出すには、パラメータを入力する必要があります.そうしないと、構文エラーが発生します.
#!/usr/bin/python3
 
#      
def printme( str ):
   "          "
   print (str);
   return;
 
#  printme  
printme();

上記の例は、結果を出力します.
Traceback (most recent call last):
  File "test.py", line 10, in 
    printme();
TypeError: printme() missing 1 required positional argument: 'str'

キーワードパラメータ
キーワードパラメータと関数呼び出しは密接に関係しており、関数呼び出しはキーワードパラメータを使用して入力されたパラメータ値を決定します.
キーワードパラメータを使用すると、Python解釈器がパラメータ名でパラメータ値を一致させることができるため、関数呼び出し時のパラメータの順序が宣言時と一致しないことができます.
次の例では、関数printme()呼び出し時にパラメータ名を使用します.
#!/usr/bin/python3
 
#      
def printme( str ):
   "          "
   print (str);
   return;
 
#  printme  
printme( str = "    ");

上記の例は、結果を出力します.
    

次の例では、関数パラメータの使用に指定した順序を使用する必要がないことを示します.
#!/usr/bin/python3
 
#      
def printinfo( name, age ):
   "          "
   print ("  : ", name);
   print ("  : ", age);
   return;
 
#  printinfo  
printinfo( age=50, name="runoob" );

上記の例は、結果を出力します.
  :  runoob
  :  50

既定のパラメータ
関数を呼び出すときにパラメータが渡されない場合は、デフォルトのパラメータが使用されます.次の例でageパラメータが入力されていない場合は、デフォルト値を使用します.
#!/usr/bin/python3
 
#      
def printinfo( name, age = 35 ):
   "          "
   print ("  : ", name);
   print ("  : ", age);
   return;
 
#  printinfo  
printinfo( age=50, name="runoob" );
print ("------------------------")
printinfo( name="runoob" );

上記の例は、結果を出力します.
  :  runoob
  :  50
------------------------
  :  runoob
  :  35

ふていちょうパラメータ
当初宣言したときよりも多くのパラメータを処理する関数が必要かもしれません.これらのパラメータは不定長パラメータと呼ばれ、上記2つのパラメータとは異なり、宣言時には名前が付けられません.基本構文は次のとおりです.
def functionname([formal_args,] *var_args_tuple ):
   "  _     "
   function_suite
   return [expression]

アスタリスク(*)を付けた変数名には、名前の付いていないすべての変数パラメータが格納されます.関数呼び出し時にパラメータが指定されていない場合は、空のメタグループです.関数に名前のない変数を渡さないこともできます.次の例を示します.
#!/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

匿名関数
pythonはlambdaを使用して匿名関数を作成します.
匿名とはdef文のような標準的な形式で関数を定義しないことを意味する.
Lambdaはただの式で、関数体はdefよりずっと簡単です.
Lambdaの本体はコードブロックではなく式です.限られた論理をlambda式にカプセル化できるだけです.
Lambda関数は独自のネーミングスペースを持ち、独自のパラメータリスト以外またはグローバルネーミングスペースのパラメータにアクセスできません.
Lambda関数は1行しか書けないように見えますが、CまたはC++のインライン関数とは等しくありません.後者の目的は、小さな関数を呼び出すときにスタックメモリを消費せずに実行効率を向上させることです.
構文
Lambda関数の構文には、次のような文が1つしか含まれていません.
lambda [arg1 [,arg2,.....argn]]:expression

次の例を示します.
#!/usr/bin/python3
 
#       
sum = lambda arg1, arg2: arg1 + arg2;
 
#   sum  
print ("       : ", sum( 10, 20 ))
print ("       : ", sum( 20, 20 ))

上記の例は、結果を出力します.
       :  30
       :  40

return文
return[式]文は、関数を終了し、呼び出し元に式を選択的に返すために使用されます.パラメータ値を持たないreturn文はNoneを返します.以前の例では、数値を返す方法を示していません.次の例では、return文の使用方法を示します.
#!/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では,プログラムの変数はどこでもアクセスできるものではなく,アクセス権限はこの変数がどこで付与されるかによって決まる.
変数の役割ドメインは、どのプログラムがどの特定の変数名にアクセスできるかを決定します.Pythonの役割ドメインは全部で4種類あり、それぞれ:
L(Local)局所作用域E(Enclosing)閉包関数外の関数のうちG(Global)グローバル役割ドメインB(Built-in)内蔵ドメインL->E->G->Bのルールで検索します.つまり、局所的に見つからないと、局所外の局所的に探します(例えば、閉パッケージ)、見つからないとグローバルに探し、さらに内蔵中に探します.
x = int(2.9)  #      
 
g_count = 0  #      
def outer():
    o_count = 1  #          
    def inner():
        i_count = 2  #      

Pythonではモジュール(module)、クラス(class)、関数(def、lambda)のみが新しい役割ドメインを導入します.他のコードブロック(if/elif/else/、try/except、for/whileなど)は新しい役割ドメインを導入しません.つまり、これらの文で定義された変数は、外部からもアクセスできます.次のコードです.
>>> if True:
...  msg = 'I am from Runoob'
... 
>>> msg
'I am from Runoob'
>>> 

インスタンスのmsg変数はif文ブロックに定義されますが、外部からアクセスできます.
msgを関数に定義すると、ローカル変数であり、外部からアクセスできません.
>>> def test():
...     msg_inner = 'I am from Runoob'
... 
>>> msg_inner
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'msg_inner' is not defined
>>> 

エラーメッセージから見て、msg_を説明しました.innerは定義されておらず、ローカル変数なので使用できません.関数内でのみ使用できます.
グローバル変数とローカル変数
関数の内部に定義された変数には局所的な役割ドメインがあり、関数の外に定義されたグローバルな役割ドメインがあります.
ローカル変数は宣言された関数の内部にのみアクセスでき、グローバル変数はプログラム全体にアクセスできます.関数を呼び出すと、関数内で宣言されたすべての変数名が役割ドメインに追加されます.次の例を示します.
#!/usr/bin/python3

total = 0; #         
#       
def sum( arg1, arg2 ):
    #  2     ."
    total = arg1 + arg2; # total        .
    print ("         : ", total)
    return total;

#  sum  
sum( 10, 20 );
print ("         : ", total)

上記の例は、結果を出力します.
         :  30
         :  0

globalとnonlocalキーワード
内部役割ドメインが外部役割ドメインの変数を変更したい場合はglobalとnonlocalキーワードを使用します.
次の例では、グローバル変数numを変更します.
#!/usr/bin/python3

num = 1
def fun1():
    global num  #      global      
    print(num) 
    num = 123
    print(num)
fun1()

上記の例は、結果を出力します.
1
123

ネストされた役割ドメイン(enclosing役割ドメイン、外層非グローバル役割ドメイン)の変数を変更するには、次の例のnonlocalキーワードが必要です.
#!/usr/bin/python3
 
def outer():
    num = 10
    def inner():
        nonlocal num   # nonlocal     
        num = 100
        print(num)
    inner()
    print(num)
outer()

上記の例は、結果を出力します.
100
100

さらに、次のコードが実行されるとします.
#!/usr/bin/python3
 
a = 10
def test():
    a = a + 1
    print(a)
test()

以上のプログラムが実行され、エラーメッセージは以下の通りです.
Traceback (most recent call last):
  File "test.py", line 7, in 
    test()
  File "test.py", line 5, in test
    a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment

エラー情報は、test関数のaがローカルで使用されているため、ローカル役割ドメイン参照エラーです.定義されていません.変更できません.