Deve usar global para acessar a variável LOCAL (não faço ideia do porquê) python;Kivy

StackOverflow https://stackoverflow.com//questions/11700648

  •  13-12-2019
  •  | 
  •  

Pergunta

Recentemente baixei o Kivy, pois ele me deu os tutoriais e a documentação mais compreensíveis, etc.Eu tentei pygame e cocos, mas nunca consegui uma base, e com Kivy tem sido fácil.

Então aqui está o meu problema: criei um jogo de pong e estou tentando fazer o jogo pausar parando a bola de pong e iniciando-a novamente quando ela for retomada (alterando sua velocidade).

Aqui está meu código:

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   

Como você pode ver nos comentários, se eu não usar global, serei referenciado antes do erro de atribuição.Mas é uma variável local, não entendo porque isso está acontecendo.

Alguém tem alguma ideia?obrigado?

Editar:Só para ter certeza de que minhas intenções estão claras para todos, NÃO quero usar um global, mas é a única maneira de funcionar.Eu preferiria não usar globais.

Foi útil?

Solução

Se você corrigir o erro de indentação novamente, verá isso:Você pode ver isso:

  1. a fuga escape deveria funcionar sem o global, no entanto tempBallVelocity será considerado como uma variável local.Se você deseja modificar uma variável global, você precisa adicionar a declaração global para informar ao python que tempBallVelocity não é local, mas global.

  2. No segundo caso, tempBallVelocity não é inicializado localmente se você não inserir o bloco de escape e, portanto, não pode ser usado como local ValorR.Neste caso o python deve procurar a variável fora da classe.É tempBallVelocity realmente uma variável global?

observação:se os casos forem exclusivos você deve usar elif em vez de if para o segundo caso.

Outras dicas

Seu código dentro da função não está indentado, isso é apenas um erro de cópia?Se não, me pergunto por que você não recebe um erro.

Editar:Ok, é fácil definir a variável tempBallVelocity quando você chama a função com 'escape' mas então a função termina e você perde a variável.Se você chamá-lo com 'backtick' você não definiu a variável tempBallVelocity ainda assim, a melhor solução provavelmente seria:self.tempBallVelocity = self.ball.velocity.

Cada vez que você define uma variável dentro de um bloco de código identificado, a variável é destruída assim que você sai desse bloco, de volta à identificação anterior;

Se você escrever

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

dentro de um script enorme, python apenas lida com a variável foo enquanto ela está 'dentro' da instrução if, e uma vez que termina e sai, foo é completamente esquecido para tornar as coisas mais rápidas, entende-se que se você definir a variável dentro de um instrução, você a usará apenas dentro dessa instrução.

Se você quisesse fazer algo assim

if True:
    foo = 'foo value'

# Right now foo has been trashed

if True:
    print foo
    # Raises an error

Você teria que definir a variável foo fora das instruções 'if'

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'

Ou você também pode fazer isso definindo foo como uma variável global para que não seja destruída quando você sair da instrução '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

Mas isso pode ser desnecessário e confuso na maioria das circunstâncias, ou até mesmo problemático se você começar a tornar tudo global, de modo que variáveis ​​que você usa apenas uma vez se acumulem inutilmente na memória do seu dispositivo durante o programa.

No momento você está escrevendo uma classe, então a maneira certa de fazer o que está fazendo seria (do meu ponto de vista) armazenar a variável 'tempBallVelocity' na classe como esta

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   

Parece que não respeita a regra que acabei de dizer, mas o problema aqui é que quando você escreve 'self.tempBallVelocity = ...' você está armazenando a informação em self, que é o atalho para o objeto PongGame você instanciará para executar o jogo, que executará esse método, para que a variável fique armazenada lá quando você sair do método.

Espero que esta resposta seja útil para você, você deve obter um conhecimento mais sólido sobre python, Aprenda Python da maneira mais difícil é o site de um livro com versão html gratuita que foi útil para mim.

Vê você!:D

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top