[Python-es] copy.deepcopy() falla cuando el objeto a copiar tiene logging

Chema Cortes pych3m4 en gmail.com
Mie Nov 28 03:43:36 EST 2018


El mar., 27 nov. 2018 a las 8:13, Angel Lis (<anlismon en gmail.com>) escribió:

> Hola Jose,
> el problema que describes es la razon de por que existe el metodo
> copy.copy() y copy.deepcopy()
> de la documentacion:
>
> https://docs.python.org/2.7/library/copy.html
>
> """
>
>    - A *shallow copy* constructs a new compound object and then (to the
>    extent possible) inserts *references* into it to the objects found in
>    the original.
>    - A *deep copy* constructs a new compound object and then,
>    recursively, inserts *copies* into it of the objects found in the
>    original.
>
>
> """
>
> Y para el objeto logging:
>
>
> https://docs.python.org/2.7/library/logging.html?highlight=logging#thread-safety
> """
> The logging module is intended to be thread-safe without any special work
> needing to be done by its clients. It achieves this though using threading
> locks; there is one lock to serialize access to the module’s shared data,
> and each handler also creates a lock to serialize access to its underlying
> I/O.
> """
>
> En este caso, probablemente deberas usar un copy() en vez de deepcopy.
> Espero haberte ayudado.
>
>
El módulo 'logging' usa locks para bloquear los hilos que no es conveniente
duplicar, de ahí que saque el error.

Aún así, se puede aprovechar el funcionamiento que tiene 'deepcopy' para
evitar duplicar componentes que ya ha copiado en su intento de replicar
toda la estructura de un objeto. Tiene un segundo argumento para pasarle el
diccionario con el que "*memoizar*" los componentes ya duplicados. Si a
este argumento añadimos aquellos componentes que no queremos duplicar ya
debería funcionar:

c = C()
mem = { id(c.log):  c.log }
x = copy.deepcopy(c)

id(c) == id(x)  # False
id(c.log) == id(x.log)  # True




> Un saludo.
>
> PD: Yo tampoco tengo tildes en el teclado
>
> El lun., 26 nov. 2018 a las 23:30, Jose Caballero (<
> jcaballero.hep en gmail.com>) escribió:
>
>> Hola,
>>
>> tengo una clase C, a cuyos objetos puedo, en principio, hacer copias
>> con copy.deepcopy().
>> Sin embargo, cuando a la clase C le agrego logging en el __init__ [1],
>> ya no funciona [2].
>> ?No me queda mas remedio que copiar el objeto "manualmente"?
>> ?O existe alguna forma limpia de evitar este problema?
>>
>> Gracias por adelantado.
>> Un saludo, y perdon por la falta de tildes.
>> Jose
>>
>>
>> [1]
>> def __init__(self):
>>       self.log = logging.getLogger()
>>       logStream = logging.StreamHandler()
>>       ....
>>       self.log.addHandler(logStream)
>>
>> [2]
>>  File "/usr/lib64/python2.7/copy.py", line 190, in deepcopy
>>     y = _reconstruct(x, rv, 1, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 334, in _reconstruct
>>     state = deepcopy(state, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 163, in deepcopy
>>     y = copier(x, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 257, in _deepcopy_dict
>>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 190, in deepcopy
>>     y = _reconstruct(x, rv, 1, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 334, in _reconstruct
>>     state = deepcopy(state, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 163, in deepcopy
>>     y = copier(x, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 257, in _deepcopy_dict
>>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 163, in deepcopy
>>     y = copier(x, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 230, in _deepcopy_list
>>     y.append(deepcopy(a, memo))
>>   File "/usr/lib64/python2.7/copy.py", line 190, in deepcopy
>>     y = _reconstruct(x, rv, 1, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 334, in _reconstruct
>>     state = deepcopy(state, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 163, in deepcopy
>>     y = copier(x, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 257, in _deepcopy_dict
>>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 190, in deepcopy
>>     y = _reconstruct(x, rv, 1, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 334, in _reconstruct
>>     state = deepcopy(state, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 163, in deepcopy
>>     y = copier(x, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 257, in _deepcopy_dict
>>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 190, in deepcopy
>>     y = _reconstruct(x, rv, 1, memo)
>>   File "/usr/lib64/python2.7/copy.py", line 329, in _reconstruct
>>     y = callable(*args)
>>   File "/usr/lib64/python2.7/copy_reg.py", line 93, in __newobj__
>>     return cls.__new__(cls, *args)
>> TypeError: object.__new__(thread.lock) is not safe, use
>> thread.lock.__new__()
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
>
>
> --
> --
> Àngel Lis.
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>


-- 
Hyperreals *R  "Quarks, bits y otras criaturas infinitesimales":
https://blog.ch3m4.org
Buscador Python Hispano: http://busca.ch3m4.org
<https://blog.ch3m4.org/pages/busqueda-python-es/>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20181128/a382ef66/attachment.html>


Más información sobre la lista de distribución Python-es