理解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)
我希望它会通过绘制一个矩形返回,但它一直说长度没有定义,不知道在哪里放置"长度",它将识别变量。
我正在使用Python3,谢谢。
解决方案
这里有一个很好的方法来思考它。函数是一个"黑匣子",它接受一些值,称为 争论, ,在一个特定的顺序,并与他们做一些事情,以产生一些其他的价值。当我说"黑盒子"时,我的意思是当你使用该功能时,你不必关心 如何 它做它做什么,你只是给它一些值,你得到一个值回来。
让我们考虑一个非常简单的函数,它只是减去它给出的两个数字:第一个减去第二个。换句话说,我们将创建一个实现规则"参数#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
, ,你所要改变的只是一个函数中的代码。你只需将定义更改为
def subtract(first, second):
return first - second
就是这样-你的代码在功能上完全相同。程序中的其他任何地方 x
和 y
但是,它们指的是这个函数的参数以外的东西,所以当你重命名参数时,你不必改变它们。
在你的情况下发生的事情是你试图使用标签 length
在它被定义的函数之外的某个地方(即你存储为 draw_rectangle
).Python知道你不能引用你不在的函数的参数,所以它希望你已经定义了 length
意思是别的。但你没有。这就是为什么你会得到一个错误。(好吧,那一个错误,无论如何)
其他提示
你有两个问题。首先,定义函数 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
, ,它需要两个参数-一个长度和一个高度。长度由 draw_flag
功能;但是你不返回值。
你有几种方法可以解决这个问题。一个是简单地调用 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))
另一种是移动你的 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书中关于变量范围的部分。当您期望打印一些变量但遇到奇怪的错误时,它会有所帮助-特别是如果您正在使用函数。
尝试以下
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调用它们时,Python的函数接受参数,这些函数通过引用传递,这意味着您最终可以在呼叫空间中的函数中的相同数据结束。这对于可变类型很重要,因为如果它们在函数内更改,则它们也会在功能外部更改。 (str,int,float和teple不是可变的,dict和list是)。当函数返回时,将返回令牌返回到呼叫者后的值,所以如果字段,则函数输入需要一个参数让提示显示给用户,注意这是通过引用传递的,它不是字符串的副本。它返回生成的输入,存储到a。您可以从函数返回多个值,它们将自动转换为元组;如果你有
def test():
return 1,2
a,b = test()
.
您将获得= 1和b= 2。必须定义函数内使用的名称。他们首先在函数内寻求,然后在任何封闭的命名空间中,最后在内置函数中。无法使用其他函数中定义的变量,因为它们不在本地命名空间和其中的任何一个父项中。要访问这些名称的值,您必须将它们传递给函数,请注意函数中使用的名称不必匹配函数外的名称。考虑:
def fun1(a):
return a * 2
def fun2():
b = 5
c = fun1(b)
print c
fun2()
.
值5存储在名称B下的存储器中,然后通过引用传递给Fun1,此时间在名称A下,它是加倍并返回的,(返回也通过引用),然后存储返回值在名称c下,然后打印。
return
返回您将其返回给调用者的任何内容。确实如此 不是 自动使函数内部的局部变量在外部可用(这些是 本地 是有原因的!).也要注意 return
没有任何参数将返回特殊值 None
(所以相当于 return None
).
所以,如果你想返回一些值,使用 return height, length
函数内部,以及 height, length = draw_flag(A)
外面。