Vamos pegar o código a seguir como exemplo:
def programa():
numero_1 = 2
numero_2 = 4
valor = (numero_1 * numero_2)/(numero_2 - numero_1)
print(valor)
programa()
Queremos fazer uma outra função que será responsável apenas por esse "calculo complexo"
def programa():
numero_1 = 2
numero_2 = 4
calculo_complexo()
print(valor)
def calculo_complexo():
valor = (numero_1 * numero_2)/(numero_2 - numero_1)
programa()
Vai dar um erro dizendo que número_1 e numero_2 não foi definido. Isso é por causa do escopo.
#escopo A
def programa():
numero_1 = 2
numero_2 = 4
calculo_complexo()
print(valor)
#fim do escopo A
#escopo B
def calculo_complexo():
valor = (numero_1 * numero_2)/(numero_2 - numero_1)
#fim do escopo B
programa()
O que está em B não consegue enxergar A, e vice-versa.
O que nós fazemos para resolver isso?
Vamos enviar as variáveis numero_1 e numero_2 para o escopo B, que é a função calculo_complexo. Enviaremos essas por parametros, que também devem ser definidos na função calculo_complexo e deve estar na chamada do método.
#escopo A
def programa():
numero_1 = 2
numero_2 = 4
calculo_complexo(numero_1, numero_2) #chamada do método
print(valor)
#fim do escopo A
#escopo B
def calculo_complexo(numero_1, numero_2): #definição da função
valor = (numero_1 * numero_2)/(numero_2 - numero_1)
#fim do escopo B
programa()
Ainda está dando erro e pelo mesmo motivo! Agora é a variavel valor que não é enxergada no escopo A. Ela foi definida na função calculo_complexo (escopo B). Então temos o mesmo, enviar para o escopo A. Só que a função calculo_complexo não chama a função programa. Temos que enviar esses valores de outra maneira. é usando o return.
#escopo A
def programa():
numero_1 = 2
numero_2 = 4
calculo_complexo(numero_1, numero_2)
print(valor)
#fim do escopo A
#escopo B
def calculo_complexo(numero_1, numero_2):
valor = (numero_1 * numero_2)/(numero_2 - numero_1)
return valor #retorno adicionado
#fim do escopo B
programa()
Retornamos o valor, mas dentro da função programa, não estamos armazenando o retorno de calculo_complexo em nenhum lugar. Vamos armazenar esse valor em uma variável.
#escopo A
def programa():
numero_1 = 2
numero_2 = 4
valor = calculo_complexo(numero_1, numero_2) #armazenando o retorno em valor
print(valor)
#fim do escopo A
#escopo B
def calculo_complexo(numero_1, numero_2):
valor = (numero_1 * numero_2)/(numero_2 - numero_1)
return valor
#fim do escopo B
programa()
Agora o programa está funcionando. Mas não acabou por aqui. Vamos explorar um pouco mais sobre escopos.
Veja a função calculo_completo. Tudo que está dentro dela faz parte do escopo B.
Vamos mudar o nome dos parametros para ver o que acontece:
#escopo A
def programa():
numero_1 = 2
numero_2 = 4
valor = calculo_complexo(numero_1, numero_2)
print(valor)
#fim do escopo A
#escopo B
def calculo_complexo(parametro_1, parametro_2):
valor = (parametro_1 * parametro_2)/(parametro_2 - parametro_1)
return valor
#fim do escopo B
programa()
Toquei todos os numero_1 por parametro_1 e os numero_2 por parametro_2. Veja que o código ainda funciona. Vamos fazer outra mudança:
#escopo A
def programa():
numero_1 = 2
numero_2 = 4
valor = calculo_complexo(numero_1, numero_2)
print(valor)
#fim do escopo A
#escopo B
def calculo_complexo(parametro_1, parametro_2):
calculo = (parametro_1 * parametro_2)/(parametro_2 - parametro_1)
return calculo
#fim do escopo B
programa()
Troquei o nome valor por calculo no escopo B. E mesmo assim o código funciona. Nós não passamos O NOME DAS VARIAVEIS como parametro, mas sim os "O QUE ELAS ESTÃO ARMAZENANDO".
Está em aspas pq não é bem asism, mas podemos nos abstrair desse conceito para essa resposta. Se tive curiosidade, busque por "passagem por valor ou referencia"
https://medium.com/@jordanmmartin/js-pass-by-value-vs-pass-by-reference-5a8c9ebf4d14 - Aqui tem uma excelente gif explicando isso.
Espero ter ajudado.