Passando valores em Python [duplicado]
-
22-08-2019 - |
Pergunta
Esta questão já tem uma resposta aqui:
- Como faço para passar uma variável por referência? 26 respostas
Quando você passar uma coleção como lista, array para outra função em python, faz uma cópia do mesmo, ou é apenas um ponteiro?
Solução
passa referências-a-objetos por valor .
Python passa referências-a-objetos valor (como Java), e tudo Python é um objecto. Isto soa simples, mas, em seguida, você vai notar que alguns tipos de dados parecem exibir passar por valor características, enquanto outros parecem agir como passar por referência ... qual é o problema?
É importante compreender mutável e objetos imutáveis. Alguns objetos, como cordas, tuplas, e números, são imutável. Alterá-los dentro de um função / método irá criar um novo exemplo e a instância original fora da função / método não é mudado. Outros objetos, como listas e dicionários são mutáveis, que significa que você pode mudar o objeto no lugar. Portanto, uma alteração objecto dentro de uma função vontade / Método também alterar o objeto original fora.
Outras dicas
A coisa é, o conceito de referência / valor todo não se encaixam em python. Python não tem "valor" de uma variável. Python tem apenas objetos e nomes que se referem a objetos.
Assim, quando você chamar uma função e colocar um "nome" dentro do parêntese, como em:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
O objeto real que myname
está apontando é passado, não o nome myname
em si . Dentro da função outro nome (x
) é dada para se referir ao mesmo objeto passado.
Você pode modificar o objeto dentro da função se é mutável, mas você não pode mudar o que o nome fora está apontando para . Apenas o mesmo que acontece quando você faz
anothername = myname
Por isso eu posso responder à sua pergunta com:
é "passar por valor", mas todos os valores são apenas referências a objetos.
As respostas aqui têm sido úteis, mas acho que a necessidade de apresentar esse fina distinção que eu não vi coberto, o que eu tenho provado a mim mesmo com o experimento CL posterior:
- Um objeto imutável sozinho não pode ser mudado dentro de uma chamada de função. (respostas até agora disseram que muito ...)
- MAS, um objeto imutável contido dentro de um objeto mutável pode ser re-atribuído dentro de uma chamada de método.
'num' não muda aqui porque é um objeto Number imutável [suporta o meu ponto 1.]:
def incr_num(num):
num += 1
num = 0
num
0
incr_num(num)
num
0
'list [0]' aqui é um objeto Number imutável também.
def incr_list(list):
list[0] += 1
list = [0]
list[0]
0
incr_list(list)
list[0]
1
Então, como fez 'lista [0]', sendo um objeto Número imutável, mudança (suporta o meu ponto 2.), enquanto o do exemplo acima Número objeto 'num' não? O objeto Number imutável 'lista [0]' está contido dentro da lista de objeto mutável 'list', enquanto 'num' do 1º exemplo é apenas um objeto não-contianed Number.
Apesar de bem intencionada, sinto @Stephen Pape mais votadas resposta (citado abaixo), e alguns outros similares, não foram totalmente correta (e que me motivou a escrever esta resposta):
Alguns objetos, como cordas, tuplas e números, são imutáveis. Alterá-los dentro de uma função / método irá criar uma nova instância e a instância original fora da função / método não é alterado.
Meu experimento código 2 acima mostra um objeto Number ( 'lista [0]') a ser alterada dentro de um método, e então a instância original fora da função alterada.
Uma referência é passado, mas, se o parâmetro é um objecto imutável, modificá-lo dentro do método vai criar uma nova instância.
O objeto é passado. Não uma cópia, mas uma referência para o objeto subjacente.
Eu também recomendo a olhar para o módulo copy
:
documentação Python para cópia
Ele vai ajudar você a entender as questões subjacentes e como usá-lo para realizar a sua própria cópia profunda.
Por referência:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
Por favor, deixe-me dar um exemplo humilde
def swap(a, b):
x = a
print id(x)
print id(a)
print id(b)
a = b
print id(a)
b = x
print id(b)
a[0]= '20'
var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)
swap(var1, var2)
print id(var1)
print id(var2)
print var1
print var2
que produz o seguinte resultado
28329344 var1 28331264 var2 28329344 x 28329344 um 28331264 b Depois de a = b 28331264 um depois b = x 28329344 b após o retorno 28329344 var1 28331264 var2 [ '1' '2', '3', '4'] [ '20', '6', '7', '8', '9']
Mapeamento para os endereços de memória 28329344 28331264 var1 var2 a b X Depois de a = b uma Após b = x b Depois de um [0] = '20' [0] = '20' após o retorno [ '1' '2', '3', '4'] [ '20', '6', '7', '8', '9']