2012-02-24 23 views
6

Tengo este ejercicio en un examen de Python. Tratar de devolver una copia profunda o de una lista como esta:Python, copia en profundidad de la lista en la asignación

l = list() 
l = [0,1,2] 
l1 = l 
l[0] = 1 

L1 debe contener [0,1,2] no [1,1,2]

El ejercicio especificada para ponerlo en práctica mediante el uso de una metaclase.

class deep(type): 
    def __new__(meta, classname, bases, classDict): 
     return type.__new__(meta, classname, bases, classDict) 
    def __init__(cls, name, bases, dct): 
     super(deep, cls).__init__(name, bases, dct) 
    def __call__(cls, *args, **kwds): 
     return type.__call__(cls, *args, **kwds)    
class list(metaclass=deep): 
    def __init__(self): 
     pass 

Por lo que sé, el '=' en Python es una declaración y no un operador y no se puede anular. ¿Alguna idea sobre cómo devolver una copia profunda en una tarea? He estado intentando bastante pero sin éxito.

+3

En resumen, no se puede. E incluso si algún hacker ingenioso encuentra la manera, nunca ** debe ** ser usado. Y no estoy haciendo afirmaciones generales así, créanme. – delnan

+4

Este es un ejercicio bastante extraño, dado que puede realizar una copia profunda con solo tres caracteres utilizando la notación de división ('l1 = l [:]'). Usar metaclases se siente excesivo aquí. –

+0

Si esta es una pregunta de examen para la escuela, le sugiero que simplemente la cierre. Pidiéndonos ayuda con su examen es el colmo de la trampa académica. –

Respuesta

1

Que yo sepa, esto no es posible en Python sin usar algún tipo de sintaxis adicional. Como dijiste, no puedes anular =.

+0

pero podría usar el método '__repr__' para lograr resultados similares. ¡simplemente no devuelva una cadena sino una nueva clase! –

+0

@DonQuestion: ¿Se llama a '__repr__' para vincular un nombre? Eso parece extraño. – Daenyth

+0

@Daenyth No lo es. Don Question está desviado. – delnan

1

Para entender lo que l1 = l hace en Python, lea Other languages have "variables", Python has "names".

para cambiar lo l[0] = 1 hace usted podría anular l 's __setitem__() método:

>>> class L(list): 
...  def __setitem__(self, i, v): 
...   list.__setitem__(self, i, 10) 
... 
>>> l = L() 
>>> l.append(1) 
>>> l 
[1] 
>>> l[0] = 0 
>>> l 
[10] 

para cambiar lo l = List(); l = [0,1,2] hace se podría definir List.__del__() método en el CPython y manipular el espacio de nombres l pertenece a, por ejemplo, usando inspect módulo. No hace falta decir que nunca debes hacer eso.

>>> import inspect 
>>> class L: 
...  def __del__(self): 
...   inspect.currentframe().f_globals['l'] = [1,2,3] 
... 
>>> l = L() 
>>> l = [0] 
>>> l 
[1, 2, 3] 
Cuestiones relacionadas