2012-02-24 15 views
6

Bu alıştırmayı bir python sınavında aldım. Böyle bir listenin derin o kopyasını döndürmek için çalışılıyor:Ödevdeki listenin Python derin kopyası

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

l1 [0,1,2] içermelidir değil [1,1,2]

bir metaclass kullanarak uygulamak belirtilen egzersiz. Bildiğim kadarıyla

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 

, Python '=' bir açıklama değil, bir operatör ve bu overriden olamaz. Ödev üzerinde derin bir kopyanın nasıl iade edileceğine dair bir fikrin var mı? Çok fazla deniyor ama başarıya ulaşmıyor.

+3

, yapamazsın. Ve usta bir hacker bile bir yol bulursa, ** asla ** kullanılmamalıdır. Ve ben böyle kolayca battaniye ifadeleri yapmıyorum, inan bana. – delnan

+4

Bu oldukça garip bir alıştırmadır, çünkü sadece üç karakterle dilim notasyonu ('l1 = l [:]') kullanarak derin bir kopya yapabilirsiniz. Metakımların kullanılması burada aşırı bir his veriyor. –

+0

Bu, okul için bir sınav soruysa, bunu kapatmanızı öneriyorum. Sınava yardımcı olmak için bize sormamız akademik aldatmanın yüksekliğidir. –

cevap

1

Farkında olduğum kadarıyla, bu bir çeşit ekstra sözdizimi kullanmadan python'da bu mümkün değildir. Söylediğiniz gibi, ='u geçersiz kılabilirsiniz. l1 = l Python ne yaptığını anlamak için

+0

ama benzer sonuçlar elde etmek için '__repr__' yöntemini kullanabilir! Sadece bir dize değil, yeni bir sınıf döndürme! –

+0

@DonQuestion: __repr__' bir adı bağlama çağrısında bulunuyor mu? Bu garip görünüyor. – Daenyth

+0

@Daenyth Değil. Don Soru kapalıdır. – delnan

1

Other languages have "variables", Python has "names" okuyun. inspect modülü kullanarak,

>>> 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] 

l = List(); l = [0,1,2] Eğer l birimleri gibi yerlere ait ad CPython içinde List.__del__() yöntemini tanımlamak ve manipüle olabilir ne yaptığını değiştirmek için:

l[0] = 1 Eğer l 'ın __setitem__() yöntem geçersiz olabilir ne yaptığını değiştirmek için. Söylemeye gerek yok ki bunu asla yapmamalısın. Kısacası

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