2012-02-24 27 views
6

Có bài tập này về bài kiểm tra python. Đang cố gắng để trả về một bản sao o sâu sắc về một danh sách như thế này:Bản thảo sâu của Python về danh sách

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

l1 nên chứa [0,1,2] không [1,1,2]

Cuộc diễn tập quy định để thực hiện nó bằng cách sử dụng một metaclass.

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 

Từ những gì tôi biết, các '=' trong python là một tuyên bố và không phải là một nhà điều hành và nó không thể được ghi đè. Bất kỳ ý tưởng về cách trả lại một bản sao sâu về chuyển nhượng? Đã cố gắng khá nhiều nhưng không thành công.

+3

Tóm lại, bạn không thể. Và ngay cả khi một số hacker khéo léo tìm thấy một cách, nó sẽ ** không bao giờ ** được sử dụng. Và tôi không làm những câu nói dễ như vậy, hãy tin tôi đi. – delnan

+4

Đây là một bài tập khá lạ, vì bạn có thể thực hiện một bản sao sâu chỉ với ba ký tự sử dụng ký hiệu slice ('l1 = l [:]'). Sử dụng metaclasses cảm thấy quá mức cần thiết ở đây. –

+0

Nếu đây là câu hỏi thi cho trường, tôi đề nghị bạn chỉ cần đóng nó. Yêu cầu chúng tôi giúp đỡ với kỳ thi của bạn là chiều cao của gian lận học thuật. –

Trả lời

1

Theo như tôi biết, điều này là không thể trong python mà không sử dụng một số loại cú pháp bổ sung. Như bạn đã nói, bạn không thể ghi đè =.

+0

nhưng ông có thể sử dụng phương pháp '__repr__' để đạt được kết quả tương tự! chỉ không trả lại một chuỗi mà là một lớp mới! –

+0

@DonQuestion: Có phải '__repr__' được gọi là ràng buộc tên không? Điều đó có vẻ lạ. – Daenyth

+0

@Daenyth Nó không phải là. Don Câu hỏi là theo dõi. – delnan

1

Để hiểu những gì l1 = l thực hiện bằng Python đọc Other languages have "variables", Python has "names".

Để thay đổi những gì l[0] = 1 không bạn có thể ghi đè lên l 's __setitem__() phương pháp:

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

Để thay đổi những gì l = List(); l = [0,1,2] không bạn có thể xác định List.__del__() phương pháp trong CPython và thao tác các namespace l thuộc về ví dụ, sử dụng inspect module. Không cần phải nói rằng bạn không bao giờ nên làm điều đó.

>>> import inspect 
>>> class L: 
...  def __del__(self): 
...   inspect.currentframe().f_globals['l'] = [1,2,3] 
... 
>>> l = L() 
>>> l = [0] 
>>> l 
[1, 2, 3] 
Các vấn đề liên quan