Referencing Python Variables

Asked

Viewed 250 times

2

I’m learning programming on my own and no matter how I look online, I can’t understand exactly why the following reference doesn’t work as I imagine it would work.

Let’s say I created a function to ask a question:

def Pergunta(X, Y):  
    X = input(Y)

Then I call the method and add a greeting:

Pergunta(Resposta, 'Qual o seu nome?')
print('Sejam bem-vindos, {}'.format(Resposta))

Python then claims that the variable Resposta is not defined, therefore, I imagine I need to reference the variable before and this was my solution:

def Pergunta(X, Y):  
    X = input(Y)

Resposta = ''
Pergunta(Resposta, 'Qual o seu nome?')
print('Sejam bem-vindos, {}!'.format(Resposta))

Apparently that solves the problem, but when I test the program, the reference in which Resposta = '' is not superimposed by the function that should transform it into "Leandro", for example. Instead, the program only prints:

Sejam bem-vindos, !

Can anyone explain to me what I’m doing wrong or why the function doesn’t rewrite the reference or what I should do to make it work that way ?

One thing that confuses me: when I write this command inside the method format, for some reason the reference works, but I wanted this greeting to be independent of the method.

Thank you for your attention.

2 answers

1


First of all, you should know that the variable Resposta and the variable X in your function are different. First because the nomenclature is different, then if you want to change the variable Resposta, you should have within your function a variable with the same name. Example:

def Pergunta(Y):  
    Resposta = input(Y)

Note two things in this example above. The first thing is that I removed the parameter X method signature. Maybe you think when passing Resposta for X you pass the reference, but it doesn’t work with primitive types in Python, in fact, what you do is pass only the value of the variable.

Passing the reference as an argument to a function only works in objects as lists, tuples, and others. Example:

# O que é passado para o parâmetro não é um valor e sim um endereço de memória, 
# já que se é passado uma lista e não um tipo primitivo.

def limpa(lista):  
    lista.clear()

minhaLista = [1,2,3]
limpa(minhaLista)

The second thing we can notice when executing this function is that even correcting the variable name problem, the result will still not be what we want or even an error will be generated, like what happened to you before.

def Pergunta(Y):  
    Resposta = input(Y)

Pergunta('Qual o seu nome?')
print('Sejam bem-vindos, {}!'.format(Resposta))

Nameerror: name 'Reply' is not defined

This is because the variable Resposta within the function is in a totally different scope from the variable Resposta out of the function. Then the error in the above example is generated because the variable Resposta exists only within the function.

To better understand the subject scope I recommend you read the article in this site. But simplifying everything, the scope of the variable within its function is the scope local and outside the function, its variable is in the scope global.

Resposta = ""  # Escopo global

def Pergunta(Y):  
    Resposta = input(Y)  # Escopo local

The variable of the scope global will not be changed as the scope local has no connection with it. But we can change the variable of the scope global within the function using the global. See below:

def Pergunta(Y): 

    # Declara que a variável não pertence 
    # ao escopo local, e sim ao escopo global. 
    global Resposta

    Resposta = input(Y)

There is also another statement called nonlocal which has the same objective as the declaration global, but it will get the variable of the scope of the most external function. Example:

# Escopo global (fora de funções, classes, métodos e outros)

def obterIdade(): # Escopo da função 1 (dentro da função obterIdade)

    idade = 15

    def acrescentaIdade(): # Escopo da função 2 (dentro da função acrescentaIdade)

        # Utilizar a declaração global não funcionaria pois a variável
        # não está no escopo global, e sim no escopo local da função 1.
        nonlocal idade
        idade += 1

Other than that, you should also know about the return. This statement serves to return one or more values of a function. Thus it is not necessary to change the variable directly in the function global. Example:

def Pergunta(Y):  
    nome = input(Y)
    return nome

resposta = Pergunta('Qual o seu nome?') # Obtém o valor retornado da função
print('Sejam bem-vindos, {}!'.format(resposta))

Now that you’ve learned all about scopes, statement global and nonlocal, you can fix and improve your code in this way:

# Dica: Tenha sempre a atenção de criar nomes 
# bem definidos para suas variáveis e funções ;)

def perguntar(texto):
    global resposta
    resposta = input(texto)

perguntar('Qual o seu nome?')
print('Sejam bem-vindos, {}!'.format(resposta))
  • Jeanextreme002, very grateful: this is exactly what I needed to understand! Practically a class!

  • I’m sorry to impose. I managed to make it work, but when I went to import this function to another document I realized that the situation repeats with the reference, even assigning "Global" to the variable. I read the article you referred to me, but I didn’t find mention of a scale outside or above the global to make them talk and Return didn’t bridge the gap between the scopes either. In this case the reference only works if the function is inside the file itself, then?

  • Regarding this your first question, I recommend that you ask another question on the site so that I or others can answer you, and as you said, return does not bridge between scopes really. What the command return does simply return a value, but the variable used within the function dies at the end of the performance of the function. So you can’t reuse the variable created within the function, but you can get the value returned by the function with the assignment signal as I demonstrated in my example.

  • I understood. I then created another doubt, since the subject seems to be another. Grateful!

0

Important to remember that in python string are immutable with this if passing an immutable type in a method will not be passed its reference, therefore it will not be possible to change.

But if you do this with a changeable object, like a list, for example. The reference passage will be made through the method and thus it will be possible to change the object. Using your example only changing the type of the variable of string for list

Resposta = list()

def Pergunta(X, Y):
    X.append(input(Y))

Pergunta(Resposta, 'Qual o seu nome?')
print('Sejam bem-vindos, {}!'.format(Resposta[0]))

We have the following output:

Qual o seu nome? Thiago
Sejam bem-vindos, Thiago!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.