Deve usar global para acessar a variável LOCAL (não faço ideia do porquê) python;Kivy
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.
Solução
Se você corrigir o erro de indentação novamente, verá isso:Você pode ver isso:
a fuga
escape
deveria funcionar sem o global, no entantotempBallVelocity
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 quetempBallVelocity
não é local, mas global.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