Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Dúvida entre retorno/paramêtros nas funções

Fiquei com uma dúvida entre 2 funções do exemplo:

a primeira inicializa_letras_acertadas

#Código omitido
    letras_acertadas = inicializa_letras_acertadas(palavra_secreta)
    print(letras_acertadas)
#Código omitido

def inicializa_letras_acertadas(palavra):
    return ["_" for letra in palavra]

ela recebe a palavra_secreta como parametro cria a lista e retorna a lista para a variável letras_acertadas

e a função marca_chute

#Código omitido

        chute = pede_chute()

        if (chute in palavra_secreta):
            marca_chute_correto(chute, letras_acertadas, palavra_secreta)

#Código omitido

def marca_chute_correto(chute, letras_acertadas, palavra_secreta):
    index = 0
    for letra in palavra_secreta:
        if (chute.upper() == letra.upper()):
            letras_acertadas[index] = letra
        index += 1

ela recebe chute, letras_acertadas, palavra_secreta a variável é manipulada dentro da função, mas a função não retorna letras_acertadas e o restante do código consegue visualizar essa alteração.

Não poderíamos fazer assim, e não ter o retorno na função?

#Código omitido
    letras_acertadas = []
    inicializa_letras_acertadas(letras_acertadas, palavra_secreta)
    print(letras_acertadas)
#Código omitido

def inicializa_letras_acertadas(palavra):
    letras_acertadas = ["_" for letra in palavra]

já testei o código acima e printou "[]"

tem alguma diferença sutil nessas 2 implementações?

3 respostas
solução!

Olá Roberto. Para resumir, você gostaria de criar uma variável global, não é isso? As variáveis globais são acessíveis em todo lugar do módulo (arquivo.py), porém como somente leitura. Isso quer dizer que não é possível atribuir da maneira tradicional um novo objeto à variável, apesar de ser possível mudar seu estado através de seus métodos, como o append do tipo list.

Na função abaixo o que aconteceu é que você criou uma nova variável no escopo da função com o mesmo nome da variável global. Por isso vc não consegue acessá-la mais desta maneira:

def inicializa_letras_acertadas(palavra):
    letras_acertadas = ["_" for letra in palavra]

Receber letras_acertadas como parâmetro dá certo porque ela é uma referência para o objeto que foi passado para a função. Portanto as mudanças nesse objeto refletem, naturalmente, em todas as variáveis que o referenciam, como no código abaixo:

def inicializa_letras_acertadas(palavra):
    letras_acertadas.extend(["_" for letra in palavra])

Percebe porque assim dá certo?

Na verdade existe uma forma de alterar uma variável global (o objeto o qual ela referencia). Basta usar a palavra reservada global:

def inicializa_letras_acertadas(palavra):
    global letras_acertadas
    letras_acertadas = ["_" for letra in palavra]

Assim você terá o comportamento que deseja. Por outro lado, não é aconselhável métodos alterarem o valor de uma variável global, porque pode ficar difícil monitorar as suas mudanças de valores. É uma boa prática as funções no python serem auto-contidas, e receberem como parâmetro todos os valores de que precisa, ou no máximo ler as variáveis de um escopo externo.

Olá Thiago, acho que já entendi, fiz um código de teste:

def jogar():
    palavra_secreta = "banana"
    letras_acertadas = inicializa_letras_acertadas(palavra_secreta)
    print(letras_acertadas)
    chute = "a"
    marca_chute_correto(chute, letras_acertadas, palavra_secreta)
    print(letras_acertadas)

def inicializa_letras_acertadas(palavra):
    return ["_" for letra in palavra]

def marca_chute_correto(chute, letras_descoberta, palavra):
    index = 0
    for letra in palavra:
        if (chute.upper() == letra.upper()):
            letras_descoberta[index] = letra
        index += 1
    letras_descoberta = []

if (__name__ == "__main__"):
    jogar()

a execução do código retornou:

['_', '_', '_', '_', '_', '_']
['_', 'a', '_', 'a', '_', 'a']

a segunda função recebe o array letras_acertadas como letras_descoberta manipula ela e depois na última linha que fiz

letras_descoberta = []

essa alteração não prevaleceu para o restante do código

Então se eu passo um parâmetro para a função posso "alterar" ele que depois poderá ser acessado no restante do código como o append e outras manipulações das variáveis, mas se "criar" uma nova referência o python interpreta que é uma variável nova dentro do escopo da função e não atribuindo um valor novo para a letras_descoberta passado como parâmetro .

Vlw

"Então se eu passo um parâmetro para a função posso "alterar" ele que depois poderá ser acessado no restante do código como o append e outras manipulações das variáveis, mas se "criar" uma nova referência o python interpreta que é uma variável nova dentro do escopo da função e não atribuindo um valor novo para a letras_descoberta passado como parâmetro ."

Exatamente isso, Roberto!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software