python copy return-value deep-copy

En python, devolver un objeto creado en un cuerpo de función hace una copia profunda de él?



title in python plot (3)

Trataré de aclarar:

Por ejemplo, realizo una función que localmente crea una lista y la devuelvo. ¿Cómo crea Python la lista devuelta que existe fuera del cuerpo de la función? ¿Utiliza "deepcopy" (o algo similar)?

In [50]: def create_list(): ...: sublist1 = [1,2,3] ...: sublist2 = [4,5,6] ...: list_of_lists=[sublist1,sublist1,sublist2] ...: return list_of_lists ...: In [51]: l=create_list() In [52]: l Out[52]: [[1, 2, 3], [1, 2, 3], [4, 5, 6]] In [53]: l[0].append(4) In [54]: l Out[54]: [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]

Aquí, la lista devuelta todavía contiene las sublistas. Y l[0] y l[1] todavía hacen referencia a la misma sublista (que es el comportamiento normal de Python). Entonces la lista y su estructura fueron copiadas.

Y si llamo una vez más create_list() :

In [55]: l2=create_list() In [56]: l2 Out[56]: [[1, 2, 3], [1, 2, 3], [4, 5, 6]] In [57]: l Out[57]: [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]

Se ha creado una nueva lista l2 , pero no se ve afectada, lo que significa que existe fuera de la función, y sus sublistas son propias, no referencias a sublistas que todavía existirían en el cuerpo de la función.

Entonces mi pregunta es si Python usa Deepcopy o algo similar para hacer l ? No importa qué tipo de objeto regrese con una función, ¿no se verá afectado por la siguiente llamada a esta función? (siempre que el objeto se haya creado localmente en la función)

No dude en decirme si no estoy lo suficientemente claro. Gracias,


Cuando ejecuta la función por segunda vez, se vuelve a ejecutar la función completa; no tiene memoria en la línea de "última vez, la sublist1 fue [1, 2, 3] " .

No ha copiado la lista [1, 2, 3] . Lo has creado dos veces.

Tenga en cuenta que si utiliza un decorador de caché como @functools.lru_cache , obtendrá resultados sorprendentes:

>>> @lru_cache() ... def create_list(): ... sublist1 = [1,2,3] ... sublist2 = [4,5,6] ... list_of_lists=[sublist1,sublist1,sublist2] ... return list_of_lists ... >>> l = create_list(); l [[1, 2, 3], [1, 2, 3], [4, 5, 6]] >>> l[0].append(4); l [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]] >>> create_list() [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]

Porque en este caso, python tiene una memoria del resultado anterior y devuelve el mismo objeto


Las variables en Python son punteros a los objetos. Por lo tanto, una función devolvería un puntero a un objeto creado en la función, obviando la necesidad de copiar los valores devueltos.


Esto podría no responder directamente a esta pregunta, pero debería ayudar a aclarar el concepto relacionado.

Si crea un objeto anidado dentro de una función y lo devuelve, el objeto continuará existiendo. No saldría del alcance aunque la función terminara.

Código de ejemplo

class Some_Class (object): prop_x = None def __init__(self, prop_x ): self.prop_x = prop_x def __repr__(self): return "prop_x = "+repr (self.prop_x) def fx (): dict_x = { "k1" : "v1" } print hex ( id (dict_x) ) obj1 = Some_Class ( prop_x = dict_x ) print hex ( id (obj1.prop_x) ) print "obj1 is "+repr( obj1 ) return obj1 recv_obj = fx () print "recv_obj is "+repr( recv_obj ) print hex ( id (recv_obj.prop_x) )

Salida

0xdfaae0 0xdfaae0 obj1 is prop_x = {''k1'': ''v1''} recv_obj is prop_x = {''k1'': ''v1''} 0xdfaae0

Un dict, dict_x , se asigna a la variable prop_x de un objeto de Clase obj1 . El dict no se crea nuevamente en la memoria, sino que tiene lugar una soft copy . prop_x apunta a la ubicación de memoria de dict_x .

Cuando devuelve el objeto obj1 al final de esta función, dict_x sale del alcance pero la dirección de memoria utilizada por él, 0xdfaae0 , todavía apunta por prop_x en el objeto recv_obj . Entonces, los valores dict { "k1" : "v1" } se conservan en la memoria.