2010-08-14 37 views
18

Tôi đã cố gắng tạo lớp con dict kế thừa từ UserDict.DictMixin hỗ trợ khóa không thể băm. Hiệu suất không phải là một mối quan tâm. Thật không may, Python thực hiện một số chức năng trong DictMixin bằng cách cố gắng tạo một đối tượng dict từ lớp con. Tôi có thể tự mình triển khai, nhưng tôi bị kẹt trên __cmp__.Có mô tả về cách __cmp__ hoạt động cho các đối tượng dict trong Python 2 không?

Tôi không thể tìm thấy mô tả ngắn gọn về logic được sử dụng bởi lớp được xây dựng trong __cmp__ cho lớp dict.

Trả lời

26

Nếu bạn đang yêu cầu như thế nào so sánh điển tác phẩm, nó là thế này:

  • Để so sánh dicts A và B, đầu tiên so sánh độ dài của họ. Nếu chúng không bằng nhau, sau đó trả về cmp (len (A), len (B)).
  • Tiếp theo, tìm adiff chính trong A là khóa nhỏ nhất mà adiff not in B or A[adiff] != B[adiff]. (Nếu không có khóa như vậy, các dấu gạch ngang bằng nhau.)
  • Cũng tìm thấy dấu phân cách nhỏ nhất trong B mà bdiff not in A or A[bdiff] != B[bdiff].
  • Nếu adiff! = Bdiff, sau đó trả lại cmp (adiff, bdiff). Khác trả lại cmp (A [adiff], B [bdiff]).

Trong pseudo-code:

def smallest_diff_key(A, B): 
    """return the smallest key adiff in A such that adiff not in B or A[adiff] != B[bdiff]""" 
    diff_keys = [k for k in A if k not in B or A[k] != B[k]] 
    return min(diff_keys) 

def dict_cmp(A, B): 
    if len(A) != len(B): 
     return cmp(len(A), len(B)) 
    try: 
     adiff = smallest_diff_key(A, B) 
    except ValueError: 
     # No difference. 
     return 0 
    bdiff = smallest_diff_key(B, A) 
    if adiff != bdiff: 
     return cmp(adiff, bdiff) 
    return cmp(A[adiff], b[bdiff]) 

này được dịch từ việc thực hiện 2.6.3 trong dictobject.c.

+0

Cảm ơn bạn! – DannoHung

+1

Bạn có biết rằng bằng cách đọc nguồn cho 'dict_compare' (http://svn.python.org/projects/python/trunk/Objects/dictobject.c) hoặc nó được ghi lại ở đâu đó? – unutbu

+3

Tôi đọc nguồn. –

0

Có một mô tả về __cmp__here, nhưng tôi nghĩ điều quan trọng cần lưu ý là __cmp__ chỉ được sử dụng nếu “so sánh giàu” phương pháp, chẳng hạn như __lt____eq__ không được định nghĩa. Hơn nữa, trong Python3, __cmp__ bị xóa khỏi ngôn ngữ. Vì vậy, có lẽ eschew __cmp__ hoàn toàn và chỉ cần xác định __lt____eq__.

+0

Vâng, tôi chỉ đang cố gắng tạo giao diện phù hợp với 2,4 dict (yêu cầu công việc). Tôi có lẽ sẽ làm đầy đủ trên cổng 3.x của mã này sau. – DannoHung

2

Cách khác là sử dụng Ánh xạ ABC từ gói collections. Nó có sẵn từ 2.6 trở lên. Bạn vừa kế thừa từ collections.Mapping và triển khai các phương thức __getitem__, __contains____iter__. Bạn nhận được tất cả mọi thứ khác miễn phí.

Các vấn đề liên quan