Python の関数を理解する
-
12-12-2019 - |
質問
PythonのTurtleモジュールを使用して、別の関数を使用してアメリカ国旗を描画しようとしています。最初にすべての寸法を計算するdraw_flagがあり、次に実際に国旗の形状を描画するdraw_rectangleがあり、次にdraw_starsなどを作成して、星と線。
しかし、関数がどのように機能するかを理解するのに少し苦労しています。これまでのコードは次のとおりです。
import turtle
import time
import random
def draw_rectangle(length, height):
turtle.up()
x = length
y = height
turtle.begin_fill()
turtle.setpos(x,y)
turtle.down()
turtle.forward(418)
turtle.right(90)
turtle.forward(220)
turtle.right(90)
turtle.forward(418)
turtle.right(90)
turtle.forward(220)
turtle.end_fill()
turtle.sleep(2)
turtle.bye
def draw_flag(A):
height = int(A)
## length = height*1.9
## union_height = height*(7/13)
## union_length = length*(2/5)
## E = F = union_height/10
## G = H = union_length/12
## stripe_width = height/13
## diameter_star = stripe_width*(4/5)
length = height*1.9
return
A = input("Please enter the height of the flag: ")
draw_rectangle(length, height)
長方形を描画して返されることを期待していましたが、長さが定義されていないと言い続け、変数を認識する「長さ」をどこに配置すればよいかわかりません。
Python 3 を使用しています、ありがとう。
解決
これについて考える良い方法があります。関数は、いくつかの値を受け取る「ブラック ボックス」です。 引数, 、特定の順序でそれらを使用して何かを行い、他の値を生成します。「ブラックボックス」とは、機能を使用するときに何も気にする必要がないことを意味します。 どうやって それはそれが行うべきことを行い、それにいくつかの値を与えるだけで、値が返されます。
与えられた 2 つの数値を減算するだけの非常に単純な関数を考えてみましょう。最初の値から 2 番目の値を引いたもの。つまり、ルール「引数#1-引数#2」を実装する関数を作成します。この関数のコードを書いているとき、引数#1を使用する場合、および引数#2を使用するときにコンピューターに伝える方法が必要です。他のプログラミング言語では、使用する引数の番号 (#1 または #2) を明示的に指定する必要がありますが、これらの値に名前を付けることができれば、コードを記述するのがはるかに簡単になります。したがって、Python では、他のほとんどの言語と同様に、選択した名前を使用して関数の引数を参照できます。たとえば、引数 #1 を次の名前の下に置きたいとします。 x
, 、および引数 #2 がその名前の下に置かれます y
. 。これを次のように書くことで示すことができます。
def subtract(x, y):
この後に、関数を構成するコードが続きます。減算の例では、次のようになります。
def subtract(x, y):
return x - y
Pythonコンパイラがこれに遭遇すると、コードを「値#1-値#2を計算し、発信者に送り返す」という内部表現に変換されます。次に、コードのブロックを詰め込み、名前の下に保存します subtract
(関数に名前を付けたいと伝えたからです)。
このコード ブロックの実行が終了すると、関数なしでは引数を持つことができないため、「引数 #1」または「引数 #2」を参照することは意味がなくなることが理解できれば幸いです。同様に、関数がその役目を終えると、引数に付けたラベルは、 x
そして y
, 、もはや意味がありません。ラベルは、関数のコードが存続している間のみ存在します。これはと呼ばれます スコーピング:ラベルをコードの中で意味のある部分に限定します。
なぜならラベルは x
そして y
は ローカルスコープの, 、ある意味、それが何であるかさえ問題ではない、と言う人もいるかもしれません。たとえば、次のような定義があったとします。 subtract
コード内で、これらを次のように変更することを任意に決定できます。 first
そして second
, 変更する必要があるのは、その 1 つの関数内のコードだけです。定義を次のように変更するだけです
def subtract(first, second):
return first - second
それだけです。コードは機能的にはまったく同じです。プログラム内の他の場所では、 x
そして y
場合によっては、この関数の引数以外のものを参照しているため、引数の名前を変更するときに引数を変更する必要はありません。
あなたの場合に何が起こっているのかというと、ラベルを使用しようとしたということです length
定義された関数の外側のどこか (つまり、次のように保存した関数) draw_rectangle
)。Python は、自分が使用していない関数の引数を参照できないことを知っているため、既に定義されていることが期待されます。 length
別の意味で。しかし、あなたはそうしませんでした。そのため、エラーが発生します。(まあ、とにかく、その 1 つのエラー)
他のヒント
あなたには 2 つの問題があります。まず、関数を定義します draw_flag
しかし、あなたは決してそれを呼びません。
ただし、それを呼び出したとしても、関数が機能しないため、機能しません。 draw_flag
本当に何もしません。内部でいくつかの変数を定義し、終了時にそれらを破棄するだけです。長さと高さを返す必要があります return length, height
, 、その後、実行します length, height = draw_flag(A)
そして電話する draw_rectangle
それらの価値観で。(あるいは、次のようにすることもできます draw_rectangle(*draw_flag(A))
.)
length, height = draw_flag(A)
draw_rectangle(length, height)
関数は魔法のように相互に通信するわけではありません。関数は入力を受け取り、戻り値を生成します。その戻り値を別の場所で使用したい場合は、値を使用したい場所で関数を呼び出す必要があります。
関数draw_rectangle
を呼び出しており、2つの引数 - 長さと高さが予想されます。長さはdraw_flag
関数によって計算されています。しかし、値を返しません。
これを解決する方法はいくつかあります。1つは、ユーザーが提供された高さを使用してdraw_flag
関数を単に呼び出し、戻り値を保存してからdraw_rectangle
を呼び出します。
def draw_flag(A):
height = int(A)
## length = height*1.9
## union_height = height*(7/13)
## union_length = length*(2/5)
## E = F = union_height/10
## G = H = union_length/12
## stripe_width = height/13
## diameter_star = stripe_width*(4/5)
return height*1.9
A = input("Please enter the height of the flag: ")
length = draw_flag(A)
draw_rectangle(length, int(A))
.
もう1つは、input
関数にdraw_flag
を移動してから、draw_rectangle
関数の内部からdraw_flag
関数を呼び出します。これを行うと、draw_flag
関数はまったく引数を必要としません。
def draw_flag():
A = input("Please enter the height of the flag: ")
height = int(A)
## length = height*1.9
## union_height = height*(7/13)
## union_length = length*(2/5)
## E = F = union_height/10
## G = H = union_length/12
## stripe_width = height/13
## diameter_star = stripe_width*(4/5)
draw_rectangle(height*1.9, height)
draw_flag()
.
私はあなたが可変スコープに関するあなたのPython Bookのセクションを通過するべきであると思います。いくつかの変数が印刷されると予想されるが、あなたが関数を使用している場合は、特に機能を使用している場合は、後でそれは後で役立ちます。
次の
を試してくださいimport turtle
import time
import random
def draw_rectangle(length, height):
turtle.up()
x = length
y = height
turtle.begin_fill()
turtle.setpos(x,y)
turtle.down()
turtle.forward(418)
turtle.right(90)
turtle.forward(220)
turtle.right(90)
turtle.forward(418)
turtle.right(90)
turtle.forward(220)
turtle.end_fill()
turtle.sleep(2)
turtle.bye
def draw_flag(A):
height = int(A)
length = height*1.9
draw_rectangle(length,height)
return
A = input("Please enter the height of the flag: ")
draw_flag(A)
. 大丈夫、あなたのより一般的な質問に答えるために、Pythonの関数は引数を受け入れると、これらは参照によって渡されます。つまり、呼び出し側のスペースと同じ関数内で同じデータを終えます。これは変化可能なタイプにとって重要です。関数内で変更された場合は、関数外でも変更されます。 (str、int、float、tupleは、変更できません、Dict、Listは)です。関数が戻ったときに、戻りトークンの後の値が呼び出し側に渡されるので、a=input('input? ')
と言う場合、関数入力はプロンプトをユーザーに表示するための引数を取ります。これは参照によって渡されます。文字列のコピー。ユーザー生成された入力を返します。これはaに格納されます。関数から複数の値を返すことができます、それらは自動的にタプルに変換されます。
def test():
return 1,2
a,b = test()
.
a= 1とb= 2になるでしょう。関数内で使用されている名前を定義する必要があります。それらは最初に関数内で、次に囲まれた名前空間、ついに組み込み内側に求められます。他の関数で定義されている変数は、ローカルネームスペースにもその両親のいずれかではないため、使用できません。これらの名前の値にアクセスするには、関数内で使用されている名前は関数の外部に名前と一致する必要はないことに注意してください。検討してください:
def fun1(a):
return a * 2
def fun2():
b = 5
c = fun1(b)
print c
fun2()
.
値5は、名前Bの下でメモリに格納され、その名前Aの下でFUN1に渡され、aは2倍になり、返され、戻り値も保存されます。その後、その名前Cの下に印刷されます。
return
は、発信者に返すものを返します。 not は、外部にある機能内のローカル変数を自動的に作成します(これらは理由で local です)。注意を持たないreturn
も特殊値None
を返します(それで、それはreturn None
と同等です)。
だから、いくつかの値を返す場合は、関数内でreturn height, length
を使用し、height, length = draw_flag(A)
を外部に使用します。