python関数|伝参、戻り値、作用域
38037 ワード
一、関数初見
関数の生成:関数は機能を実装するコードセグメントです. defキーワードは、関数 を定義します. function関数名の表記規則は変数と同じです. 括弧は参照用です. 関数体は、関数内の論理コード です.
コードが上から下にかけて実行され、def function()に実行されると、functionという変数名を一時メモリにロードしますが、実行しません.
関数の実行:関数名+()
__を使うname_メソッドを使用して関数名を取得します.doc_uうメソッド取得関数の説明
1. 関数の戻り値
関数を書きます.関数にprintを書かないでください. 関数は機能をガイドにしています.テストの時以外はprint()を書くことができます.は、関数において、return終了関数 に遭遇する.は、関数の使用者 に値を返す.
(1)実参:関数実行者の中のパラメータを実参といいます.
①位置パラメータ:順番に、一々対応する
①位置パラメータ:順番と実務に対応し、位置パラメータは値を伝えなければなりません.
例1.
(1)関数定義時:*位置パラメータと*キーワードパラメータは、集約を表します.
すべての実参照の位置パラメータを一つの元のグループにまとめ、このタプルをargsに割り当てます.重要なパラメータの前に「*」を加えると、実際に参加したキーワードパラメータを辞書に集めて、この辞書をkwargsに割り当てます.
2つのリストのすべての要素をargsに割り当てます.
*argsパラメータは、デフォルトでは空()、****kwargsダイナミックなパラメータではなく、すべてのキーワードパラメータ(未定義)を辞書に入れます.
関数に複数の未知のパラメータが含まれている場合、通常は以下のフォーマットを使います.
関数を実行する時、彼はメモリの中で一時的な名前空間を開拓して、関数の体内のすべての変数と値の関係を保存して、関数の実行が終わると、臨時の空間は自動的に閉じます.
関数内の変数は、関数の外で直接参照できますか?
まず、Pythonコードが実行されているときの関数との出会いを思い出します.Pythonインタプリタから実行を開始した後、メモリの中に一つの空間を開きます.変数が発生するたびに、変数名と値との間の対応関係を記録しますが、関数定義があるときには、関数名をメモリに読み込むだけです.この関数が存在していることを示します.関数内部の変数や論理については、解釈器はまったく関心がありません.関数が呼び出されると、Python解釈器はメモリをもう一つ開けてこの関数の内容を保存します.この時、関数の中にどの変数があるかに注目します.関数内の変数は新しく開発されたメモリに保存されます.関数内の変数です.関数の内部でのみ使用できます.関数の実行が終わると、このメモリの内容は全部空になります.
1. 名前空間とスコープ
名前空間:保存”名前と値の関係の空間”
①グローバル名前空間:コードが実行中に作成された記憶”変数名と値の関係”のメモリ空間
②ローカル名前空間:関数呼び出し時に一時的に開いた空間は、関数の実行が完了するとクリアされます.
③名前空間の内蔵:python解釈器が提供してくれた名前:input、print、str、list、tuple…これらは私たちが熟知しているので、持ってきても使える方法です.
作用域:作用範囲です.
①グローバルスコープ:グローバル名前空間、名前空間を内蔵します.ファイル全体の任意の位置で参照され、グローバル効果があります.
②ローカルスコープ:ローカル名前空間は、ローカル範囲内でのみ有効となります.
読み込み順序:
名前空間を内蔵(プログラム実行前にロード)--> グローバル名前空間(プログラム実行中に上から下にロード)->ローカル名前空間(プログラム実行中:呼び出し時にロードする)
値を取る順序:
ローカル呼び出し:ローカル名前空間->グローバル名前空間->名前空間を内蔵する
グローバル呼び出し:グローバル名前空間->名前空間を内蔵する
以上のように、変数を探すときは、小さな範囲から大きな範囲までを一階ずつ探していきます.
ローカル変数の例
コードは上から下まで順次実行されます.関数は上から下まで順次実行されます.
①ローカル名前空間でグローバル変数を宣言する
(2)nonlocal
①親関数の変数をサブ関数で変更します.この変数はグローバル変数ではありません.
例1
関数の生成:関数は機能を実装するコードセグメントです.
li = ['spring', 'summer', 'autumn', 'winter']
def function():
count = 0
for j in li:
count += 1
print(count)
function() # 4
コードが上から下にかけて実行され、def function()に実行されると、functionという変数名を一時メモリにロードしますが、実行しません.
関数の実行:関数名+()
__を使うname_メソッドを使用して関数名を取得します.doc_uうメソッド取得関数の説明
def func1():
"""
, ... 。
return: (True,False)
"""
print(666)
func1()
print(func1.__name__) #
print(func1.__doc__) #
:
666
func1
, ... 。
return: (True,False)
これは何に使いますか?例えばログ機能は、誰がいつ、どの関数を呼び出して、関数が何をするかをプリントアウトする必要があります.何度も時間がかかります.この時、関数の有益な情報を得る必要があります.1. 関数の戻り値
関数を書きます.関数にprintを書かないでください. 関数は機能をガイドにしています.テストの時以外はprint()を書くことができます.
def fun():
print(111)
return
print(444)
fun()
:111
def fun():
a = 134
return a
print(fun())
:123
1)リセットなしdef fun():
pass
print(fun())
:None
2)return 1つの値.この値は何ですか?直接関数の引数、関数名()に戻ります.def fun():
return [1,2,3]
print(fun())
:[1, 2, 3]
3)return複数の値は複数の値を一つのタプルに入れ、関数の引数の引数に返します.def fun():
return 1,2,[33,44],'abc'
print(fun())
:
(1, 2, [33, 44], 'abc')
2. 関数の参照(1)実参:関数実行者の中のパラメータを実参といいます.
①位置パラメータ:順番に、一々対応する
def func(a,b,c):
print(a)
print(b)
print(c)
func('fdsafdas',3,4)
:
fdsafdas
3
4
もしパラメータが一つ足りないなら?def func(a,b,c):
print(a)
print(b)
print(c)
func(3,4)
:TypeError: func() missing 1 required positional argument: 'c'
いちいち対応しなければなりません.def compare(x,y):
ret = x if x > y else y # , if else
return ret
print(compare(123,122334)) # 122334
②キーワードパラメータ:順番でなくてもいいですが、いちいち対応しなければなりません.def compare(x,y):
ret = x if x > y else y
return ret
print(compare(y=13,x=1))
:13
③混合パラメータ:キーワードパラメータは位置パラメータの後ろに必ずあります.def func1(a,b,c,d,e):
print(a)
print(b)
print(c)
print(d)
print(e)
func1(1,4,d=2,c=3,e=5)
:
1
4
3
2
5
(2) イメージ:①位置パラメータ:順番と実務に対応し、位置パラメータは値を伝えなければなりません.
def func(a,b,c):
print(a)
print(b)
print(c)
func('fdsafdas',3,4)
:
fdsafdas
3
4
②デフォルトのパラメータ:パラメータが上書きされ、パスしないとデフォルトで、デフォルトのパラメータは常に位置パラメータの後ろにあります.例1.
def func(a,b=666):
print(a,b)
func(1,2)
:1 2
例2.def func(a,b=666):
print(a,b)
func(1)
:1 666
一つの場面を挙げます.担任が社員情報表に記入します.二つの問題があります.第一、男性が多いです.第二に、関数機能を完成しました.def Infor(username,sex=' '):
with open('name_list',encoding='utf-8',mode='a') as f1:
f1.write('{}\t{}
'.format(username,sex))
while True:
username = input(' ( 1 ):').strip()
if '1' in username:
username = username[1:] # 1
Infor(username)
else:
Infor(username,' ')
③ダイナミックパラメータ:関数の参照数が一定でない場合、ダイナミックパラメータが使用できます.&argsと**kwargsで受信し、argsは母集団タイプで、キーパッドペア以外のパラメータ(受信位置パラメータ)を受信し、kwargsは辞書タイプで、キーパッドペア(キーワードパラメータ)を受信し、辞書に保存します.def func(*args,**kwargs):
print(args,type(args))
print(kwargs,type(kwargs))
func(1,2,3,4,'alex',name = 'alex')
:
(1, 2, 3, 4, 'alex')
{'name': 'alex'}
「*」の魔性作用(1)関数定義時:*位置パラメータと*キーワードパラメータは、集約を表します.
すべての実参照の位置パラメータを一つの元のグループにまとめ、このタプルをargsに割り当てます.重要なパラメータの前に「*」を加えると、実際に参加したキーワードパラメータを辞書に集めて、この辞書をkwargsに割り当てます.
2つのリストのすべての要素をargsに割り当てます.
def func(*args):
print(args)
l1 = [1,2,30]
l2 = [1,2,33,21,45,66]
func(*l1)
func(*l1,*l2)
:
(1, 2, 30)
(1, 2, 30, 1, 2, 33, 21, 45, 66)
二つの辞書を**kwargsに伝えます.def func(**kwargs):
print(kwargs)
dic1 = {'name':'jack','age':22}
dic2 = {'name1':'rose','age1':21}
func(**dic1,**dic2)
:
{'name': 'jack', 'age': 22, 'name1': 'rose', 'age1': 21}
def func(*args,**kwargs):
print(args)
print(kwargs)
func(*[1,2,3], *[4,5,6], **{'name':'alex'}, **{'age':18}) # func([1,2,3,4,5,6], {'name':'alex','age':18})
(2)在函数的调用执行时,打散
*可迭代对象,代表打散(list,tuple,str,dict(键))将元素一一添加到args。
**字典,代表打散,将所有键值对放到一个kwargs字典里。
def func(*args,**kwargs):
print(args,kwargs)
dic1 = {'name':'jack','age':22}
dic2 = {'name1':'rose','age1':21}
func(*[1,2,3,4],*'asdk',**dic1,**dic2)
:(1, 2, 3, 4, 'a', 's', 'd', 'k') {'age1': 21, 'name': 'jack', 'age': 22, 'name1': 'rose'}
イメージの順序:位置パラメータ-->args-->キーワードパラメータ---->デフォルトパラメータ ------->**kwargs*argsパラメータは、デフォルトでは空()、****kwargsダイナミックなパラメータではなく、すべてのキーワードパラメータ(未定義)を辞書に入れます.
def func(a,b,c,d,*args,e=' ',**kwargs):
print(a,b,c,d,args,e,kwargs)
func(1,2,3,4,5,6,7,v=3,m=7,h=9,e=' ')
:1 2 3 4 (5, 6, 7) {'v': 3, 'h': 9, 'm': 7}
def func(a,b,c,**kwargs):
print(kwargs)
func(1,2,r=4,b1=5,c1=6,c=7)
:{'r': 4, 'c1': 6, 'b1': 5}
エラーが発生していないのは、関数がパラメータを受信した後、左から右に探して、最後にc=7パラメータを見つけました.a、b、cの中で定義されていますので、出力の辞書には現れていません.kwargsは未定義のキーワードパラメータを返します.関数に複数の未知のパラメータが含まれている場合、通常は以下のフォーマットを使います.
def func1(*args,**kwargs):
pass
func1()
二、名前空間とスコープ関数を実行する時、彼はメモリの中で一時的な名前空間を開拓して、関数の体内のすべての変数と値の関係を保存して、関数の実行が終わると、臨時の空間は自動的に閉じます.
関数内の変数は、関数の外で直接参照できますか?
def func1():
m = 1
print(m)
print(m) # NameError: name 'm' is not defined
上記はなぜエラーを報告しましたか?python内部の原理を分析してみます.まず、Pythonコードが実行されているときの関数との出会いを思い出します.Pythonインタプリタから実行を開始した後、メモリの中に一つの空間を開きます.変数が発生するたびに、変数名と値との間の対応関係を記録しますが、関数定義があるときには、関数名をメモリに読み込むだけです.この関数が存在していることを示します.関数内部の変数や論理については、解釈器はまったく関心がありません.関数が呼び出されると、Python解釈器はメモリをもう一つ開けてこの関数の内容を保存します.この時、関数の中にどの変数があるかに注目します.関数内の変数は新しく開発されたメモリに保存されます.関数内の変数です.関数の内部でのみ使用できます.関数の実行が終わると、このメモリの内容は全部空になります.
1. 名前空間とスコープ
名前空間:保存”名前と値の関係の空間”
①グローバル名前空間:コードが実行中に作成された記憶”変数名と値の関係”のメモリ空間
②ローカル名前空間:関数呼び出し時に一時的に開いた空間は、関数の実行が完了するとクリアされます.
③名前空間の内蔵:python解釈器が提供してくれた名前:input、print、str、list、tuple…これらは私たちが熟知しているので、持ってきても使える方法です.
作用域:作用範囲です.
①グローバルスコープ:グローバル名前空間、名前空間を内蔵します.ファイル全体の任意の位置で参照され、グローバル効果があります.
②ローカルスコープ:ローカル名前空間は、ローカル範囲内でのみ有効となります.
読み込み順序:
名前空間を内蔵(プログラム実行前にロード)--> グローバル名前空間(プログラム実行中に上から下にロード)->ローカル名前空間(プログラム実行中:呼び出し時にロードする)
値を取る順序:
ローカル呼び出し:ローカル名前空間->グローバル名前空間->名前空間を内蔵する
グローバル呼び出し:グローバル名前空間->名前空間を内蔵する
以上のように、変数を探すときは、小さな範囲から大きな範囲までを一階ずつ探していきます.
ローカル変数の例
name = 'summer'
def func1():
name = 'spring'
print(name)
func1()
:spring
name = 'summer'
def func1():
print(name)
func1()
実行出力:summerコードは上から下まで順次実行されます.関数は上から下まで順次実行されます.
print(111)
def func1():
print(333)
func2()
print(666)
def func2():
print(444)
def func3():
print(555)
func2()
func1()
print(222)
:
111
333
444
666
222
def f1():
def f2():
def f3():
print("in f3")
print("in f2")
f3()
print("in f1")
f2()
f1()
:
in f1
in f2
in f3
2. globalsとlocasの方法print(globals()) # ,
print(locals()) # , ( )
globals()とlocars()は一般的にはあまり使われていません.関数論理が複雑な場合に使用されるかもしれません.li = ['spring', 'summer', 'autumn', 'winter']
def func():
a = 1
b = 2
print('func', globals())
print('func', locals())
def func1():
c = 3
d = 4
print('func1', globals())
print('func1', locals())
func1()
func()
出力結果func {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.sourcefileloader object="" at="">, '__spec__': None, '__annotations__': {}, '__builtins__': 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/houseinfo/test.py', '__cached__': None, 'li': ['spring', 'summer', 'autumn', 'winter'], 'func': }
func {'b': 2, 'a': 1}
func1 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.sourcefileloader object="" at="">, '__spec__': None, '__annotations__': {}, '__builtins__': 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/houseinfo/test.py', '__cached__': None, 'li': ['spring', 'summer', 'autumn', 'winter'], 'func': }
func1 {'d': 4, 'c': 3}
(1)global:①ローカル名前空間でグローバル変数を宣言する
def func2():
global name
name = 'summer'
func2()
print(name)
:summer
②グローバル変数は、ローカル名前空間で変更されます.count = 1
def func1():
global count
count = count + 1
print(count)
func1()
print(count)
:
2
2
大域変数countは関数体のglobal countによって 上書きしました(2)nonlocal
①親関数の変数をサブ関数で変更します.この変数はグローバル変数ではありません.
a = 4
def func1():
nonlocal a
a = 5 #
#print(name)
func1()
print(a)
:SyntaxError: no binding for nonlocal 'a' found
②ローカルスコープでは、親レベルのスコープの変数を参照して修正し、どのレイヤーを参照するかは、その層および以下の変数からすべて変わります.例1
def func1():
b = 6
def func2():
b = 666
print(b)
func2()
print(b) #
func1()
:
666
6
例2def func1():
b = 6
def func2():
nonlocal b # , func1()
b = 666 #
print(b)
func2()
print(b) # , b , 666
func1()
:
666
666
例3*********def aa(): # ccl
b = 42
def bb():
b = 10 # ,b 10
print(b)
def cc():
nonlocal b # , bb()
b = b + 20 #b=10+20 30
print(b)
cc()
print(b)
bb()
print(b)
aa()
:
10
30
30
42
注意a = 5
def func1():
a += 1
print(a)
func1()
エラーを実行します.この関数はグローバル変数を変更しました.操作は許可されていません.関数の内部はグローバル変数を参照することができます.変更はできません.globalが必要です.a = 5
def func1():
global a
a += 1
print(a)
func1() # 6