必须使用global来访问LOCAL变量(不知道为什么)python; Kivy

时间:2012-07-28 11:33:06

标签: python global local kivy

我最近下载了Kivy,因为它给了我最易于理解的教程和文档等等。我尝试过pygame和cocos但是从来没有得到过基础,而且对于Kivy来说它很容易。

所以继续我的问题,我做了一个乒乓球比赛,我试图通过停止乒乓球来暂停比赛,然后在它取消暂停时(通过改变其速度)再次启动它。

这是我的代码:

class PongGame(Widget):
   ...

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'escape':
        #Why doesnt it work without global?
        #If I don't use a global i get "tempBallVelocity referenced before assignment
            global tempBallVelocity
            tempBallVelocity = self.ball.velocity
            self.ball.velocity = 0,0


        if keycode[1] == '`':
            #Make the ball go again, thus exiting pause
            #This is where the error occurs if I don't use global
            self.ball.velocity = tempBallVelocity   

正如您在评论中看到的那样,如果我不使用全局,我会在分配错误之前被引用。但它是一个局部变量,我不明白为什么会发生这种情况。

有人有什么想法吗?感谢?

编辑:为了确保每个人都清楚我的意图,我不想使用全局,但它是唯一可行的方式。我宁愿不使用全局变量。

3 个答案:

答案 0 :(得分:1)

你的函数里面的代码没有缩进,只是一个复制错误?如果不是,我想知道为什么你没有收到错误。

编辑: 好吧,当您使用tempBallVelocity调用函数时,很容易设置变量'escape',但随后函数退出并松开变量。如果你用“反引号”调用它,你还没有设置变量tempBallVelocity,最好的解决方案可能是: self.tempBallVelocity = self.ball.velocity

答案 1 :(得分:1)

如果再次修复缩进错误,您将看到: 你可以看到:

  1. 转义escape应该在没有全局的情况下工作,但tempBallVelocity将被视为局部变量。如果你想修改一个全局变量,你需要添加全局声明来告诉python tempBallVelocity不是本地的,而是全局的。

  2. 在第二种情况下,如果您未输入转义块,则tempBallVelocity未在本地初始化,因此无法用作本地RValue。在这种情况下,python应该在类之外查找变量。 tempBallVelocity真的是一个全局变量吗?

  3. 备注:如果案例是独占的,则应使用elif代替if来处理第二种情况。

答案 2 :(得分:0)

每次在一个标识的代码块中设置一个变量时,一旦你离开那个块,变量就会被破坏,回到之前的标识中;

如果你写

if True:
    foo = 'foo value, which is a string (?)'
    print foo

在一个巨大的脚本中,python只处理foo变量,而它在if语句的“内部”,一旦它结束并退出,foo就完全被遗忘以便加快速度,你可以理解,如果你设置了在语句中的变量,你只会在该语句中使用它。

如果你想做这样的事情

if True:
    foo = 'foo value'

# Right now foo has been trashed

if True:
    print foo
    # Raises an error

您必须在'if'语句

之外设置foo变量
foo = ''

if True:
    foo = 'foo value'

# Right now foo still exists and keeps it's recently changed value

if True:
    print foo
    # prints 'foo value'

或者你也可以通过将foo设置为全局变量来实现它,这样一旦你超出'if'语句就不会销毁它

if True:
    global foo
    foo = 'foo value'

# foo still exists as it's a global variable

if True:
    print foo
    # There's no reason so it wouldn't work

但是在大​​多数情况下这可能是不必要的和令人困惑的,或者如果你开始把所有东西都变成全局的话甚至会有问题,所以你只使用过一次的变量就会在你的设备内存中无用地累积。

现在你正在编写一个类,所以正确地做你正在做的事情就是(从我的观点来看)将'tempBallVelocity'变量存储在类中

class PongGame(Widget):
   ...

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'escape':
            self.tempBallVelocity = self.ball.velocity
            self.ball.velocity = 0,0


        if keycode[1] == '`':
            self.ball.velocity = self.tempBallVelocity   

看起来它不尊重我刚刚告诉你的规则,但这里的事情是,当你写'self.tempBallVelocity = ...'时,你在自我中存储信息,这是快捷方式您将实例化PongGame对象以运行游戏,该游戏将运行该方法,因此当您拿出该方法时,变量将存储在那里。

我希望这个答案对你有所帮助,你应该对python有一个更加扎实的了解,Learn Python The Hard Way是一本书的网站,有一个对我有用的免费html版本。

见! :d