8.7 Objetos São Acessados Por Referência
O programa pode manter na memória não apenas uma Conta , mas mais de uma:
minha_conta = Conta() minha_conta.saldo =
meu_sonho = Conta() meu_sonho.saldo = 1500000
Quando criamos uma variável para associar a um objeto, na verdade, essa variável não guarda o objeto, e sim uma maneira de acessá-lo, chamada de referência (o self).
c1 = Conta()
Ao fazer isso, já sabemos que o Python está chamando os métodos mágicos new () e
init () que são responsáveis por construir e iniciar um objeto do tipo Conta .
O correto é dizer que c1 se refere a um objeto. Não é correto dizer que c1 é um objeto, pois c1 é uma variável referência. Todavia, é comum ouvir frases como “tenho um objeto c1 do tipo Conta ”, mas isso é apenas uma abreviação para encurtar a frase “Tenho uma referência c1 a um objeto tipo Conta “.
Vamos analisar o código abaixo:
c1 = Conta(‘123-4’, ‘João’, 120.0, 1000.0)
c2 = c1 print(c2.saldo) #120.0
c1.deposita(100.0) print(c1.saldo) #220.0
c2.deposita(30.0) print(c2.saldo) #250.0
print(c1.saldo) #250.0O que aconteceu aqui? O operador ”=” copia o valor de uma variável. Mas qual é o valor da variável c1 ? É o objeto? Não. Na verdade, o valor guardado é a referência (endereço) de onde o objeto se encontra na memória principal.
Ao fazer c2 = c1 , c2 passa a fazer referência para o mesmo objeto que c1 referencia nesse instante. Quando utilizamos c1 ou c2 neste código, estamos nos referindo ao MESMO objeto – são duas referências que apontam para o mesmo objeto.
Podemos notar isso através da função interna id() que retorna a referência de um objeto:
print(id(c1)) #140059774918104print(id(c2)) #140059774918104Internamente, c1 e c2 vão guardar um número que identifica em que posição da memória aquela Conta se encontra. Dessa maneira, ao utilizarmos o ”.” (ponto) para navegar, o Python vai acessar a Conta que se encontra naquela posição de memória, e não uma outra conta. Para quem conhece, é parecido com um ponteiro, porém você não pode manipulá-lo.
Outra maneira de notar esse comportamento é que o interpretador Python chamou os métodos
new () e init () apenas uma vez (na linha c1 = Conta(‘123-4’, ‘João’, 120.0, 1000.0) ), então só pode haver um objeto Conta na memória. Compará-las com o operador ”==” vai nos retornar True , pois o valor que elas carregam é o mesmo:
print(id(c1) == id(c2)) #Trueprint(c1 == c2) #TruePodemos então ver outra situação:
c1 = Conta(“123-4”, “Python”, 500.0, 1000.0)
c2 = Conta(“123-4”, “Python”, 500.0, 1000.0)
if(c1 == c2):
print("contas iguais")O operador "" compara o conteúdo das variáveis, mas essas variáveis não guardam o objeto, e sim o endereço em que ele se encontra. Como em cada uma dessas variáveis guardamos duas contas criadas diferentemente, elas estão em espaços diferentes da memória, o que faz o teste no if valer False . As contas podem ser equivalentes no nosso critério de igualdade, porém elas não são o mesmo objeto. Quando se trata de objetos, pode ficar mais fácil pensar que o "" compara se os objetos (referências, na verdade) são o mesmo, e não se possuem valores iguais.
Para saber se dois objetos têm o mesmo conteúdo, você precisa comparar atributo por atributo.
Futuramente, veremos uma solução mais elegante para isso também.