El paso de valor y el paso de referencia en Python (objetos mutables y objetos inmutables) es el principio de asignación: Python es todo paso de referencia

El paso de valor y el paso de referencia en Python (objetos mutables y objetos inmutables) es el principio de asignación: Python es todo paso de referencia

20141215 Chenxin

Adivina:
1. Los objetos que pertenecen a la misma clase, las propiedades predeterminadas apuntan a la misma referencia. De esta manera, cuando modifiques un objeto, afectará a otros objetos, a menos que lo modifiques a través de otros métodos en la clase. De hecho, todos deberían ser Es el concepto de punteros.
2. La "variable" básica es el "objeto" inmutable, que es el valor de la llamada. Cuando reasigna el valor "=", Python crea un nuevo valor (objeto) internamente Darlo. (Esto es lo que comúnmente se conoce como transferencia de valor). No importa qué tipo de transferencia sea, sin rodeos, Python es toda transferencia de referencia.
3. Para "objetos mutables" como lista, dict y objetos predeterminados, completamente Es una forma de pasar por referencia. Es una referencia a una dirección en la memoria, como un puntero.
4. Si desea copiar un objeto a otros objetos (en forma de copia), solo se puede lograr a través del módulo de copia de Python.
5. Python tiene un caché El concepto de rango entero en caché es (-5, 256). Otros tipos no se almacenarán en caché. Por ejemplo, x = 1, y = 1, x es y; x = 257, y = 257, x no es y; id (*) Para verificar la dirección de memoria.

Prueba:
La explicación del paso de parámetros de función es la siguiente (3 ejemplos): <<< Tutoriales básicos de Python Segunda edición >> P93
def ChangeInt (a):
a = 10
b = 2
ChangeInt (b)
print b # -> 2 se
traduce en La no función se ve así:
b = 2
a = b # La dirección de memoria de a es la misma que b, lo que indica que se trata de una copia de la dirección de memoria, por lo que la asignación puede entenderse como un puntero que apunta a
a = 10 # señalando a al objeto 10 recién creado, La dirección de memoria de a ha cambiado.
Imprimir b

Def ChangeList (a):
a [0] = 10
b = [2]
ChangeList (b)
print b # -> [10] se
traduce como no funcional:
b = [2]
a = b # la dirección de memoria de a es la misma que b Lo mismo, lo que indica que se trata de una copia de la dirección de memoria, por lo que la asignación puede entenderse como un puntero a
un [0] = 10 # punto el valor del primer elemento de la lista señalado por un nuevo objeto 10 creado en la memoria, la dirección de memoria de a no ha cambiado Sigue siendo la misma que la dirección de memoria de b. Lo que se cambia aquí es solo la dirección del primer elemento en la lista, y la dirección de a no se cambia (es decir, la dirección de toda la lista señalada por a).
Imprimir b

def ChangeList (a):
a = [10]
b = [2]
ChangeList (b)
print b # -> [2]
traducido a no función:
b = [2]
a = b # la dirección de memoria de a es la misma que b Sí, significa que esta es una copia de la dirección de memoria, por lo que la asignación puede entenderse como un puntero que apunta a
a = [10] # Recrea una nueva lista, apunta a esta nueva lista y la dirección de memoria de a ha cambiado.
Imprimir b

Conclusión:
Resumiendo los 3 ejemplos anteriores, puede entenderse como:
1. La asignación en la declaración Python "=" puede entenderse como el apuntar del puntero.
2. Debido al problema de apuntar el puntero, el concepto de "alcance" se derivó en lugar de El resultado anterior causado por la "limitación artificial" del alcance, ¿no?
3. Preste atención a la diferencia entre objetos variables y objetos inmutables. List, dict, int, char, tuple ...
4. Esto también se inicia El concepto de paso de valor y paso de referencia puede entenderse uniformemente como paso de referencia en Python.

Explicación:
La situación real de int inmutable:

La situación real de la lista de variables:

Formas de pasar la referencia del objeto de clase y el objeto de instancia:

! / bin / env python

class
class_a (): num_a = 'abc' # ¿Qué pasa cuando la cadena es lo suficientemente larga? ¿Será un caché de Python? El efecto es el mismo, no el caché
a = class_a
b =
class_a a.num_a = 'xyz' # No importa que la longitud de la cadena sea la misma,
imprima a.num_a, b.num_a #Output xyz xyz
print id (a.num_a), id ( b.num_a) # Salida de la misma dirección de memoria
En esta clase, no importa cómo cambiar el objeto a, el objeto b cambiará en consecuencia.
Explique que el objeto es un objeto variable. El objeto de clase es solo un espacio de memoria inicial, y luego se generará el objeto de instancia Rellene los valores. ? ?

<< Fin >>
Conocimiento

De hecho, no hay mucha diferencia en Python. Lo principal es que Python crea un objeto por asignación.
Entonces, para los objetos en python, a = '1' no se puede llamar modificación, solo creación. Si crees que esto es una modificación, estás equivocado.
Una vez que se utiliza la instrucción de asignación, es básicamente independiente del objeto original. # Realmente un puntero re-apuntando

Y Python también tiene objetos mutables y objetos inmutables:
como los tipos simples, enteros, cadenas, tuplas son inmutables.
Y como list, dict, object son variables. Por lo tanto, la modificación de ellos generalmente es llamar al método correspondiente, por ejemplo, necesita a.append (b) para la lista, y a ['b'] = '1' para dict.
El objeto en sí no cambia, sus propiedades o valores cambian. Para todos estos casos, pasar por valor o por referencia es lo mismo.

Sin embargo, se puede decir que la referencia es más precisa, por ejemplo:
def b (c):
print id (c)
a = [2]
print id (a)
b (a)
Verá que el valor de id impreso es el mismo dos veces . La descripción es por referencia.
En otras palabras, el objeto señalado por el parámetro en la función b es a.
No importa pasar por valor, porque desde la perspectiva de la asignación, la asignación en la función creará un nuevo objeto sin afectar los parámetros originales.

Es más razonable utilizar el concepto de punteros para comprender.

De hecho, el nombre de la variable y el objeto real en Python es una relación vinculante o relación de referencia. Por lo tanto, es más apropiado entender la referencia.

A diferencia de otros lenguajes, Python no permite a los programadores elegir si pasar valores o referencias al pasar parámetros. El paso de parámetros de Python debe usar el método "referencia de objeto de paso". De hecho, este método es equivalente a una combinación de pasar por valor y pasar por referencia. Si la función recibe una referencia a un objeto mutable (como un diccionario o una lista), puede modificar el valor original del objeto equivalente a pasar el objeto "pasando por referencia". Si la función recibe una referencia a un objeto inmutable (como números, caracteres o tuplas), no puede modificar directamente el objeto original equivalente a pasar el objeto "pasando por valor".

Python generalmente asigna variables internamente, es una variable de referencia, que es similar al concepto de dirección C. Puede usar id () para consultar la dirección de la memoria.
Si a = b, las direcciones de a y b son las mismas;
si solo desea copiar, entonces debe usar b = a [:], para que las direcciones de memoria de a y b sean diferentes Sobre

a = [1,2]; b = a [:]; # aquí a y b apuntan a una dirección de memoria llamada lista, la lista almacena las direcciones de memoria correspondientes a los valores específicos. La lista es una dirección de doble capa;
id (a)
140337215511368
id (b)
140337215510288 #diferente

a = 'abc'; b = a [:]; # Aquí hay una forma de cadena, a apunta a la dirección de memoria de 'abc', después de b = a [:] (equivalente a b = a), b también apunta a La dirección de memoria de 'abc'. La cadena es una dirección de una sola capa; la redacción aquí es un poco polimórfica.
Id (a)
140337216460600
id (b)
140337216460600 #same

La referencia se refiere al valor guardado como la dirección del objeto. En el lenguaje Python, se hace referencia a los valores que posee una variable, excepto el tipo básico que contiene el valor, por lo que debe tener cuidado con su uso. Aquí hay un ejemplo:
Descripción del problema: Conozca una lista y busque generar una nueva lista. El elemento de la lista es una copia de la lista original.
A = [1,2]
b = a
Este enfoque en realidad no genera una nueva lista. Lo que b señala sigue siendo el objeto señalado por a. De esta manera, si se modifican los elementos de aob, los valores de a y b cambian al mismo tiempo.
La solución es:
a = [1,2]
b = a [:] De
esta manera, modificar a no tiene efecto en b, y modificar b no tiene efecto en a. (La copia de la lista, es decir, la copia. No por referencia)
Pero este método solo es adecuado para listas simples, es decir, los elementos en la lista son tipos básicos. Si los elementos de la lista todavía existen en la lista, este método no es aplicable. La razón es que un proceso como [:] solo genera una nueva lista del valor del elemento de la lista. Si el elemento de la lista también es una lista, como: a = [1, [2]], entonces esta copia es para el elemento [ El procesamiento de 2] simplemente copió la referencia de [2], pero no generó una nueva copia de la lista de [2].
Si resuelve este problema, puede usar la función de copia profunda en el módulo de copia. La prueba modificada es la siguiente:
importar copia
a = [1, [2]]
b = copia.deepcopy (a)
imprimir b-> [1, [2]]
a [1] .append (3)
imprimir a-> [ 1, [2, 3]]
imprimir b-> [1, [2]]
A veces es muy importante saber esto, porque es posible que necesite una nueva lista, y opere en esta nueva lista, y no quiera afectar la lista original.

Supongo que te gusta

Origin www.cnblogs.com/chanix/p/12737696.html
Recomendado
Clasificación