2012-07-17 12 views
26

Tôi đang cố gắng kết nối qua telnet với một thiết bị phòng thí nghiệm. Tôi muốn mở rộng các lớp Telnet từ các module telnetlib trong thư viện chuẩn, bao gồm các chức năng cụ thể để công cụ của chúng tôi:Python - kế thừa từ các lớp học kiểu cũ

import telnetlib 
class Instrument(telnetlib.Telnet): 
    def __init__(self, host=None, port=0, timeout=5): 
     super(Instrument,self).__init__(host, port, timeout) 

Tất cả tôi đang cố gắng để làm trong mã này được kế thừa phương pháp __init__ từ phụ huynh lớp học (telnetlib.Telnet) và vượt qua các đối số chuẩn, vì vậy tôi có thể thêm mọi thứ vào __init__ sau đó. Công thức này đã làm việc cho tôi vào những dịp khác; lần này nó mang lại cho tôi một lỗi ở câu lệnh super() khi tôi cố gắng để nhanh chóng:

TypeError: must be type, not classobj 

tôi nhìn vào mã nguồn cho telnetlib, và Telnet dường như là một lớp kiểu cũ (nó không kế thừa từ object) - Tôi tự hỏi nếu điều này có thể là nguồn gốc của vấn đề của tôi? Nếu vậy, làm thế nào nó có thể được khắc phục? Tôi đã nhìn thấy một số ví dụ mã nơi lớp dẫn xuất kế thừa cả hai từ lớp cha và object, mặc dù tôi không hoàn toàn chắc chắn nếu đây là một phản ứng với cùng một vấn đề như tôi.

tiết lộ đầy đủ: Tôi cũng đã cố gắng sử dụng telnetlib.Telnet ở vị trí của super(), và from telnetlib import Telnet với Telnet ở vị trí của super(). Vấn đề vẫn tồn tại trong những trường hợp này.

Cảm ơn!

Trả lời

36

Bạn cần phải gọi constructor như thế này:

telnetlib.Telnet.__init__(self, host, port, timeout) 

Bạn cần phải thêm rõ ràng self từ telnet.Telnet.__init__ không phải là một phương pháp ràng buộc mà là một phương pháp cởi ra, ví dụ: witout một thể hiện được giao. Vì vậy, khi gọi nó, bạn cần phải vượt qua dụ một cách rõ ràng.

>>> Test.__init__ 
<unbound method Test.__init__> 
>>> Test().__init__ 
<bound method Test.__init__ of <__main__.Test instance at 0x7fb54c984e18>> 
>>> Test.__init__() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method __init__() must be called with Test instance as first argument (got nothing instead) 
+0

Tôi đã thử điều đó - nó mang lại cho tôi lỗi: 'TypeError: phương thức unbound __init __() phải được gọi với cá thể Telnet làm đối số đầu tiên (có str instance)' –

+0

Vui lòng hiển thị mã và lỗi chính xác mà bạn nhận được mã tôi vừa đăng. Bởi vì đó thực sự là cách nó được thực hiện nếu bạn muốn gọi hàm tạo cha của một lớp kiểu cũ. – ThiefMaster

+0

Ah, tôi đã phát hiện sự khác biệt giữa mã của bạn và của tôi - bạn đã có 'self' làm đối số đầu tiên của' __init__'. Nó hoạt động ngay bây giờ - cảm ơn bạn đã trả lời rất nhanh! Bạn có thể giải thích cho tôi tại sao bạn cần đưa ra 'self' làm đối số đầu tiên cho nhà xây dựng? Tôi mới dùng Python. –

13

Bạn cần phải kế thừa từ object, và bạn phải đặt nó sau khi lớp học kiểu cũ bạn đang cố gắng để kế thừa từ (vì vậy mà phương pháp object 's không được tìm thấy đầu tiên):

>>> class Instrument(telnetlib.Telnet,object): 
...  def __init__(self, host=None, port=0, timeout=5): 
...   super(Instrument,self).__init__(host, port, timeout) 
... 
>>> Instrument() 
<__main__.Instrument object at 0x0000000001FECA90> 

Thừa kế từ đối tượng cung cấp cho bạn một lớp kiểu mới hoạt động với super.

+2

Có an toàn để kế thừa từ một lớp học kiểu cũ theo cách tạo ra một lớp học mới dựa trên nó không? – ThiefMaster

+0

@ThiefMaster Tôi không biết về bất kỳ vấn đề nào, nhưng tôi chưa bao giờ làm điều đó trong sự tức giận, vì vậy tôi thực sự không có thông tin. Bạn có dự đoán bất kỳ vấn đề nào không? – Marcin

+0

Tôi không quen với đa thừa kế trong Python. Vì một lớp học mới không mang lại lợi ích nào cho mục đích của tôi, tôi sẽ gắn bó với chiến lược của TheifMaster ở trên. Mặc dù dù sao đi nữa! –