31

Nói, tôi có mixins sau đó chồng chéo với nhau bằng cách chạm dispatch():Thứ tự của mixin ảnh hưởng đến lớp dẫn xuất như thế nào?

class FooMixin(object): 
    def dispatch(self, *args, **kwargs): 
     # perform check A 
     ... 
     return super(FooMixin, self).dispatch(*args, **kwargs) 

class BarMixin(object): 
    def dispatch(self, *args, **kwargs): 
     # perform check B 
     ... 
     return super(FooMixin, self).dispatch(*args, **kwargs) 

Nếu tôi muốn quan điểm của tôi phải trải qua trình tự, kiểm tra A -> kiểm tra B, nên mã của tôi được MyView(FooMixin, BarMixin, View) hoặc MyView(BarMixin, FooMixin, View) ?

Và tại sao chúng tôi luôn đặt View hoặc các lớp con sau khi kết hợp? (Tôi đã nhận thấy điều này từ việc đọc mã nguồn của chế độ xem tổng quát django, nhưng tôi không biết lý do đằng sau nó, nếu có)

Trả lời

57

MRO về cơ bản là độ sâu đầu tiên, từ trái sang phải. Xem Method Resolution Order (MRO) in new style Python classes để biết thêm thông tin.

Bạn có thể xem số __mro__ attribute của lớp học để kiểm tra, nhưng trước tiên, FooMixin nên là người đầu tiên nếu bạn muốn "đánh dấu" trước.

class UltimateBase(object): 
    def dispatch(self, *args, **kwargs): 
     print 'base dispatch' 

class FooMixin(object): 
    def dispatch(self, *args, **kwargs): 
     print 'perform check A' 
     return super(FooMixin, self).dispatch(*args, **kwargs) 

class BarMixin(object): 
    def dispatch(self, *args, **kwargs): 
     print 'perform check B' 
     return super(BarMixin, self).dispatch(*args, **kwargs) 

class FooBar(FooMixin, BarMixin, UltimateBase): 
    pass 

FooBar().dispatch() 

Prints:

perform check A 
perform check B 
base dispatch 

View phải là cuối cùng để nó "bắt" bất cứ tra cứu thuộc tính mà không được trên bất kỳ mixins, mà không che giấu bất kỳ phương pháp trên những mixins. Tôi không chắc tôi hiểu rằng một phần câu hỏi của bạn - nó là gì "tại sao nó được thêm vào" hoặc "tại sao nó được thêm vào cuối cùng"?

+1

thx agf. Câu hỏi của tôi có nghĩa là "tại sao nó được thêm vào cuối cùng" và bạn đã trả lời nó. Chúc mừng. – tamakisquare

+1

Chỉ cần rõ ràng, phương thức duy nhất mà cuộc gọi này gọi trực tiếp là 'FooMixin.dispatch'. 'super (FooMixin, self) .dispatch' sau đó đánh giá thành' BarMixin.dispatch' vì 'đối tượng' không có phương thức' dispatch'. 'super (BarMixin, self) .dispatch' đánh giá thành' UltimateBase.dispatch' cho cùng một lý do. –

+0

@MadPhysicist Điều đó không hoàn toàn đúng. Điều này sẽ làm việc ngay cả khi phương pháp này cũng được định nghĩa bởi đối tượng - tự mình thử. Xem câu trả lời được liên kết để biết thêm thông tin. – agf

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