2012-03-31 10 views
11

Raymond hettinger showed một cách thực sự mát mẻ để kết hợp các lớp học tập:subclassing từ OrderedDict và defaultdict

from collections import Counter, OrderedDict 
class OrderedCounter(Counter, OrderedDict): 
    pass 
# if pickle support is desired, see original post 

tôi muốn làm một cái gì đó tương tự cho OrderedDict và defaultdict. Nhưng tất nhiên, defaultdict có chữ ký __init__ khác nhau, vì vậy nó đòi hỏi phải có thêm công việc. Cách sạch nhất để giải quyết vấn đề này là gì? Tôi sử dụng Python 3.3.

Tôi đã tìm thấy một giải pháp tốt ở đây: https://stackoverflow.com/a/4127426/336527, nhưng tôi đã nghĩ rằng có thể xuất phát từ defaultdict có thể làm cho điều này thậm chí còn đơn giản hơn?

+3

Trong khi chúng tôi về chủ đề này, ai đó có thể giải thích cho tôi như thế nào ví dụ OrderedDict thực sự được chức năng OrderedDict mà không có bất kỳ 'super'-delegate rõ ràng đến lớp đó? Có phải vì 'super' gọi một nơi nào đó trong 'Counter' được định tuyến lại thông qua' OrderedDict' thay vì truy cập 'dict' trực tiếp như bình thường không? Hay chỉ là cái gì? –

+0

@KarlKnechtel Bạn có nghĩa là 'OrderedCounter', nhưng câu hỏi hay. – agf

+0

@agf er, vâng, chính xác. Stupid edit timeout ... :( –

Trả lời

7

Thừa kế từ OrderedDict như trong câu trả lời bạn đã liên kết đến là cách đơn giản nhất. Đó là công việc nhiều hơn để thực hiện một cửa hàng đặt hàng hơn là để có được giá trị mặc định từ một chức năng nhà máy.

Tất cả các bạn cần phải thực hiện cho defaultdict là một chút tùy chỉnh __init__ logic và cực kỳ đơn giản __missing__.

Nếu bạn thay vì kế thừa từ defaultdict, bạn phải uỷ thác cho hay tái thực hiện ít nhất __setitem__, __delitem____iter__ để tạo lại hoạt động trong trật tự. Bạn vẫn phải làm công việc thiết lập trong __init__, mặc dù bạn có thể kế thừa hoặc đơn giản là bỏ qua một số phương pháp khác tùy thuộc vào nhu cầu của bạn.

Hãy xem the original recipe hoặc any of the others linked to from another Stack Overflow question để biết điều gì sẽ đòi hỏi.

3

Tôi đã tìm thấy một cách để phân lớp cho cả hai, nhưng không chắc chắn nếu có lỗi:

class OrderedDefaultDict(defaultdict, OrderedDict): 
    def __init__(self, default, *args, **kwargs): 
     defaultdict.__init__(self, default) 
     OrderedDict.__init__(self, *args, **kwargs) 
+0

Điều đó không tạo ra hai bộ từ điển nội bộ? – leewz

+0

Ồ, tôi hiểu rồi. đọc bài đăng được liên kết trong câu hỏi gốc. – leewz