Resumo : neste tutorial, você terá um bom entendimento das referências do Python e da contagem de referências.
Introdução às referências do Python
Em Python, uma variável não é o rótulo de um valor como você pode imaginar. Em vez disso, uma variável faz referência a um objeto que contém um valor. Em outras palavras, variáveis são referências.
O exemplo a seguir atribui um número com o valor de 100
a uma variável:
counter = 100
Linguagem de código: Python ( python )
Nos bastidores, Python cria um novo objeto inteiro ( int
) na memória e vincula a counter
variável a esse endereço de memória:
Quando você acessa a counter
variável, o Python procura o objeto referenciado por counter
e retorna o valor desse objeto:
print(counter) # 100
Linguagem de código: Python ( python )
Portanto, variáveis são referências que apontam para os objetos na memória.
Para encontrar o endereço de memória de um objeto referenciado por uma variável, você passa a variável para a função integrada id()
.
Por exemplo, o seguinte retorna o endereço de memória do objeto inteiro referenciado pela counter
variável:
counter = 100
print(id(counter))
Linguagem de código: Python ( python )
Saída:
140717671523072
Linguagem de código: Python ( python )
A id()
função retorna o endereço de memória de um objeto referenciado por uma variável como um número de base 10.
Para converter este endereço de memória em uma string hexadecimal, você usa a hex()
função:
counter = 100
print(id(counter))
print(hex(id(counter)))
Linguagem de código: Python ( python )
Saída:
140717671523072
0x7ffb62d32300
Linguagem de código: Python ( python )
Contagem de referência
Um objeto no endereço de memória pode ter uma ou mais referências. Por exemplo:
counter = 100
Linguagem de código: Python ( python )
O objeto inteiro com valor 100 possui uma referência que é a counter
variável. Se você atribuir a counter
outra variável, por exemplo max
:
counter = 100
max = counter
Linguagem de código: Python ( python )
Agora, ambas counter
as max
variáveis e referenciam o mesmo objeto inteiro. O objeto inteiro com valor 100 possui duas referências:
Se você atribuir um valor diferente à max
variável:
max = 999
Linguagem de código: Python ( python )
…o objeto inteiro com valor 100 possui uma referência, que é a counter
variável:
E o número de referências do objeto inteiro com valor 100 será zero se você atribuir um valor diferente à counter
variável:
counter = 1
Linguagem de código: Python ( python )
Quando um objeto não tiver nenhuma referência, o Python Memory Manager destruirá esse objeto e recuperará a memória.
Contando referências
Para obter o número de referências de um objeto, você usa o from_address()
método do ctypes
módulo.
ctypes.c_long.from_address(address).value
Linguagem de código: Python ( python )
Para utilizar este método, você precisa passar o endereço de memória do objeto que deseja contar as referências. Além disso, o endereço precisa ser um número inteiro.
O seguinte define uma função chamada ref_count()
que usa o from_address()
método:
import ctypes
def ref_count(address):
return ctypes.c_long.from_address(address).value
Linguagem de código: Python ( python )
Agora, você pode usar uma ref_count()
função mais curta em vez de usar a sintaxe longa como acima.
Este exemplo define uma lista de três inteiros:
numbers = [1, 2, 3]
Linguagem de código: Python ( python )
Para obter o endereço de memória da numbers
lista, você usa a id()
função da seguinte forma:
numbers_id = id(numbers)
Linguagem de código: Python ( python )
A seguir mostra-se o número de referências da lista referenciada pela numbers
variável:
print(ref_count(numbers_id)) # 1
Linguagem de código: Python ( python )
Retorna um porque apenas a numbers
variável faz referência à lista.
Isso atribui a numbers
variável a uma nova variável:
ranks = numbers
Linguagem de código: Python ( python )
O número de referências da lista deve ser dois agora porque ela é referenciada pelas variáveis numbers
and :ranks
print(ref_count(numbers_id)) # 2
Linguagem de código: Python ( python )
Se você atribuir ranks
variável None
, a contagem de referências da lista será reduzida para um:
ranks = None
print(ref_count(numbers_id)) # 1
Linguagem de código: Python ( python )
E se você atribuir a numbers
variável None
, o número de referências da lista será zero:
numbers = None
print(ref_count(numbers_id)) # 0
Linguagem de código: Python ( python )
Junte tudo:
import ctypes
def ref_count(address):
return ctypes.c_long.from_address(address).value
numbers = [1, 2, 3]
numbers_id = id(numbers)
print(ref_count(numbers_id)) # 1
ranks = numbers
print(ref_count(numbers_id)) # 2
ranks = None
print(ref_count(numbers_id)) # 1
numbers = None
print(ref_count(numbers_id)) # 0
Linguagem de código: Python ( python )
Resumo
- Variáveis Python são referências a objetos localizados na memória
- Use a
id()
função para obter o endereço de memória do objeto referenciado por uma variável.