全局变量不变?

global variable doesn't change?

不管输入是什么,输出总是0,就像全局变量永远不会改变一样。请帮助我,我快疯了,因为我看不出有任何理由只显示 0

x=0
y=0
import math
import operator


def move(steps,op_func,z):
    if z == "x":
        global x
        x = op_func(x, int(steps))
    else:
        global y
        y = op_func(y, int(steps))

def main():

    user_direct=raw_input("Enter the way that you want the plane to move and how many steps you want it to move\n")
    while user_direct != " ":

        steps=user_direct[-1]
        direction=user_direct[:-1]
        directions = {"UP":move(steps,operator.add,"x"),
                      "DOWN":move(steps,operator.sub,"x"),
                      "RIGHT":move(steps,operator.add,"y"),
                      "LEFT":move(steps,operator.sub,"y")}

        directions[direction.replace(" ","")]

        user_direct=raw_input("Enter the way that you want the plane to move and how many steps you want it to move\n")

        global x
        global y
        distance=math.sqrt(x**2+y**2)
        print distance
main()

你做错了这些事情:

  • 您不是使用可以调用的函数来初始化字典,而是使用四个函数调用的结果。你真正想做的是创建一个 partial.
  • 您正在 while 循环中初始化字典。

此外,全局存储该信息并不是您真正想要做的,而是将其存储在 while 循环的范围内。

让我们看看您的字典定义在做什么:

directions = {"UP":move(steps,operator.add,"x"),
              "DOWN":move(steps,operator.sub,"x"),
              "RIGHT":move(steps,operator.add,"y"),
              "LEFT":move(steps,operator.sub,"y")}

这些赋值调用中的每一个都使用适当的值移动,并将它们设置为该值。但是,move() returns None 因为没有为那些设置 return 语句:全局变量在函数内部更新。所以在一个 while 循环之后,你的 directions 数组看起来像这样:

{"UP": None, "DOWN": None, "RIGHT": None, "LEFT": None}

并且您的 xy 全局值已分别递增和递减一次。您可以通过将 move 函数替换为以下内容来证明这一点:

def move(steps,op_func,z):
    if z == "x":
        global x
        x = op_func(x, int(steps))
        print("x is now {}".format(x))
    else:
        global y
        y = op_func(y, int(steps))
        print("y is now {}".format(y))

在 REPL 中,这是您所看到的:

>>> y= 0
>>> x= 0
>>> steps = 1
>>> directions = {"UP":move(steps,operator.add,"x"),
>>>               "DOWN":move(steps,operator.sub,"x"),
...               "RIGHT":move(steps,operator.add,"y"),
...               "LEFT":move(steps,operator.sub,"y")}
... x is now 1
x is now 0
y is now 1
y is now 0

但是,局部变量可以提供帮助:

>>> f = partial(move, op_func=operator.add, z="x")
>>> f(1)
>>> x is now 1

使用上面的方法,你想像这样定义你的 directions 地图:

directions = {"UP":partial(move, op_func=operator.add, z="x"),
              "DOWN":partial(move, op_func=operator.sub, z="x"),
              "RIGHT":partial(move, op_func=operator.add, z="y"),
              "LEFT":partial(move, op_func=operator.sub, z="y")}

这样做是用 "partial function" 替换字典中的每个 "key"。部分函数作为 一些 的参数 'filled in',稍后您可以仅使用剩余的值调用该函数。正式地:

partial(f(a, b, c), b, c) -> g(a)

每当您调用 gbc 时,将一致地为对 f.

的函数调用定义

现在你所要做的就是改变这一行:

directions[direction.replace(" ","")]

为此:

move_func = directions[direction.replace(" ","")]
move_func(steps)

重写和清理程序一点产量:

import math
import operator
from functools import partial
# Always do imports first then global vars
x=0
y=0

def move(steps,op_func,z):
    if z == "x":
        global x
        x = op_func(x, int(steps))
    else:
        global y
        y = op_func(y, int(steps))

def main():

    # We only need to define this once
    directions = {"UP":partial(move, op_func=operator.add, z="x"),
                  "DOWN":partial(move, op_func=operator.sub, z="x"),
                  "RIGHT":partial(move, op_func=operator.add, z="y"),
                  "LEFT":partial(move, op_func=operator.sub, z="y")}

    user_direct=raw_input("Enter the way that you want the plane to move and how many steps you want it to move\n")
    while user_direct != " ":
        steps=user_direct[-1]
        direction=user_direct[:-1].replace(" ","")
        move_func = directions[direction]
        move_func(steps)

        user_direct=raw_input("Enter the way that you want the plane to move and how many steps you want it to move\n")

        global x
        global y
        distance=math.sqrt(x**2+y**2)
        print distance
main()

正如我的评论所说,您的 dict 初始化实际上是 运行 那些函数并将值设置为 return 值 (NoneType)。改为做这样的事情。

1.) 在 while 循环之外启动你的命令,因为你不需要每次都重新初始化。

2.) 更改它,使值是您的参数的元组,例如:

directions = {"UP":(operator.add,"x"),
              "DOWN":(operator.sub,"x"),
              "RIGHT":(operator.add,"y"),
              "LEFT":(operator.sub,"y")}

请注意,dict 不包括步骤,因为您要将其用作每次调用的变量。

3.) 使用此行更改您的函数调用:

move(steps,directions[direction][0],directions[direction][1])

代替你当前的字典 init/dict 调用。

这个问题是如果你的命令不是一个有效的命令,它会导致错误,所以我会把所有的东西都放在一个 Try 块中,比如:

try:
    move(steps,directions[direction][0],directions[direction][1])
except KeyError:
    print('Not a valid key, try again')
else:
    #here is where you put the math code you do to edit the globals