2011-10-09 26 views
5

Tha thứ cho tôi nếu tôi không biết rõ điều này ở đây, nhưng điều gì sẽ xảy ra nếu bạn lưu một cuộc gọi đến siêu trong một biến và sử dụng nó sau này.Điều gì sẽ xảy ra nếu bạn lưu một cuộc gọi đến siêu trong một biến để sử dụng trong tương lai?

Đây là một phần của định nghĩa lớp để cho bạn thấy ý tôi.

class CaselessDict(dict): 

    def __init__(self, *args, **kwargs): 
     self.super = super(CaselessDict, self) # save super 
     self.update(*args, **kwargs) 

    def __getitem__(self, key): 
     key = self.parsekey(key) 
     return self.super.__getitem__(key) # use saved super 

Điều này xuất hiện khi tôi triển khai lớp CaselessDict này và hầu hết mọi phương pháp đều có siêu trong đó.

Trả lời

4

Điều mong đợi xảy ra: self.super sẽ chỉ giữ một đối tượng super hoạt động giống như super(CaselessDict, self).

Vấn đề với cách tiếp cận này là mỗi trường hợp chỉ có một thuộc tính super, vì vậy nếu bạn có nhiều lớp học sẽ sử dụng kỹ thuật này, chỉ có một lớp được gán cho super cuối cùng sẽ hoạt động bình thường. Ouch! Vì vậy, nó thường không phải là một ý tưởng tốt để làm điều này. Bạn có thể đặt tên cho thuộc tính __super để nó bị xáo trộn, nhưng tôi khuyên bạn chỉ cần gọi super(CaselessDict, self), như mọi người khác.

Tất nhiên, cỏ có màu xanh lá cây trong Python 3, trong đó một cuộc gọi đơn giản là super() là đủ.

0

Vũ trụ sẽ nổ tung. Không, không có gì sai xảy ra, mặc dù nó không phải là cách sử dụng thông thường. Đối với bản ghi, trong Python 3, bạn chỉ có thể sử dụng super().foo(...), do đó, về cơ bản nó là vô dụng để làm ở đó.

0

Tôi đã có một trường hợp hợp pháp khi tôi để thực hiện loại điều này, liên quan đến các lớp học được tải động và tải lại. Dưới đây là một đoạn mã sẽ nạp một module "a" có chứa lớp A, và tạo ra và thể hiện của nó:

>>> import imp 
>>> m = imp.find_module("a") 
>>> a = imp.load_module("a", *m) 
>>> a.A 
<class 'a.A'> 
>>> aobj = a.A() 
>>> aobj.__class__ 
<class 'a.A'> 

Bây giờ nếu tôi tái nhập khẩu "a", xem những gì sẽ xảy ra nếu tôi gọi isinstance với aobj tạo ra trước đó:

>>> a = imp.load_module("a", *m) 
>>> print a.A 
<class 'a.A'> 
>>> isinstance(aobj, a.A) 
False 

thế nào điều này liên quan đến siêu là như của Python 2.6, super(AClass,self) thêm việc kiểm tra để đảm bảo rằng các tài liệu tham khảo tự thực sự là một thể hiện của Aclass. Trong trường hợp của tôi, tôi đã sử dụng siêu trong một phương thức "A", nhưng khi mô-đun "a" được nhập lại và lớp "A" được xác định lại, tài liệu tham khảo siêu của tôi không còn hoạt động nữa! Lớp a.A đã thay đổi thành thứ gì đó mà các cá thể hiện tại của tôi của a.A không còn là trường hợp, và vì vậy super(a.A, self) sẽ bắt đầu tăng TypeErrors. Để giải quyết vấn đề này, tôi đã làm những gì OP đã làm: trong __init__ Tôi lưu một tham chiếu đến siêu vào một biến mẫu, sau đó được sử dụng trong các phương thức khác để upcall vào các phương thức lớp cơ sở.

Đây là toàn bộ (và có thể là một chút rambling) blog post.

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