【问题标题】:Understanding Functions in Python理解 Python 中的函数
【发布时间】:2012-10-03 04:38:57
【问题描述】:

我正在尝试使用 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,谢谢。

【问题讨论】:

  • 用户输入被存储到 A 中,在全局范围内,您没有定义长度或高度。你需要做一些像 length, height = draw_flag(A) 和里面 draw_length(A) 你需要返回 length, height

标签: python function turtle-graphics


【解决方案1】:

你有两个问题。首先,您定义了函数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)

函数之间不会神奇地相互通信。函数接受输入并产生返回值。如果要在其他地方使用该返回值,则需要在要使用该值的地方调用该函数。

【讨论】:

    【解决方案2】:

    这是一个很好的思考方式。函数是一个“黑匣子”,它以特定顺序接收一些称为 arguments 的值,并对它们执行某些操作以产生其他值。当我说“黑匣子”时,我的意思是当你使用这个函数时,你不必关心它是怎么做的,你只要给它一些值,你就会得到一个值.

    让我们考虑一个非常简单的函数,它只是减去给定的两个数字:第一个减去第二个。换句话说,我们将创建一个实现规则“argument #1 - argument #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”就不再有意义了,因为没有函数就不能有参数!同样,一旦函数完成了它的工作,你给参数的标签xy 就不再有任何意义了。标签仅在函数代码的持续时间内存在。这称为作用域:将标签限制在代码中有意义的部分。

    因为标签xy在本地范围内,正如有人可能会说的那样,从某种意义上说,它们是什么并不重要。例如,如果您的代码中有subtract 的定义,您可以任意决定将它们更改为firstsecond,您只需更改该函数中的代码即可。您只需将定义更改为

    def subtract(first, second):
        return first - second
    

    就是这样 - 您的代码在功能上完全相同。程序中出现xy 的任何其他地方,它们所指的不是此函数的参数,因此您在重命名参数时不必更改它们。

    在您的情况下发生的情况是,您尝试在为其定义的函数(即,您存储为 draw_rectangle 的函数)之外的某个地方使用标签 length。 Python 知道您不能引用您不在其中的函数的参数,因此它希望您已经将 length 定义为其他含义。但你没有。这就是你收到错误的原因。 (好吧,反正就是那个错误)

    【讨论】:

      【解决方案3】:

      您正在调用函数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_flag函数内部调用draw_rectangle函数。如果你这样做,那么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 书籍中关于变量作用域的部分。当您希望打印一些变量但遇到奇怪的错误时,它会有所帮助 - 特别是在您使用函数时。

      【讨论】:

        【解决方案4】:

        试试下面的

        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)
        

        【讨论】:

          【解决方案5】:

          好的,所以要回答您更一般的问题,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存入内存,然后通过引用传入fun1,这次在名字a下,翻倍返回,(返回也是通过引用),然后将返回值存入在名称 c 下,然后打印。

          【讨论】:

          • 所以如果我理解正确,如果 a = 2,那么 fun1(a) 将返回 4。那么 fun2() 中的 c 将返回 20?然后在最后调用 fun2() 打印 c?
          • 我不确定你在 fun2 中从哪里得到 20,b 是 5,fun1 返回两倍,将 c 设置为 10。
          【解决方案6】:

          return 将您提供的任何内容返回给调用者。它确实 not 自动使函数内部的局部变量在外部可用(这些是 local 是有原因的!)。还要注意,不带任何参数的return 将返回特殊值None(因此它等同于return None)。

          所以,如果你想返回一些值,在函数内部使用return height, length,在外部使用height, length = draw_flag(A)

          【讨论】:

            猜你喜欢
            • 2014-04-24
            • 2019-12-04
            • 2012-11-12
            • 2018-03-07
            • 1970-01-01
            • 1970-01-01
            • 2011-12-22
            • 1970-01-01
            相关资源
            最近更新 更多