2010-07-25 28 views
10

Có phải thông thường trong Python để tiếp tục thử nghiệm các giá trị kiểu khi làm việc theo kiểu OOP?Có thực hành tốt/phổ biến để kiểm tra các giá trị kiểu trong Python không?

class Foo(): 
    def __init__(self,barObject): 
     self.bar = setBarObject(barObject) 

    def setBarObject(barObject); 
     if (isInstance(barObject,Bar): 
      self.bar = barObject 
     else: 
      # throw exception, log, etc. 

class Bar(): 
    pass 

Hoặc tôi có thể sử dụng một cách tiếp cận rộng hơn, như:

class Foo(): 
    def __init__(self,barObject): 
     self.bar = barObject 

class Bar(): 
    pass 

Trả lời

19

Nope, trên thực tế đó là áp đảo chung không để kiểm tra giá trị loại, như trong cách tiếp cận thứ hai của bạn. Ý tưởng là một khách hàng của mã của bạn (tức là một số lập trình viên khác sử dụng lớp của bạn) sẽ có thể truyền bất kỳ loại đối tượng nào có tất cả các phương thức hoặc thuộc tính thích hợp. Nếu nó không xảy ra là một ví dụ của một số lớp học cụ thể, đó là tốt; mã của bạn không bao giờ cần phải biết sự khác biệt. Điều này được gọi là gõ vịt, vì câu ngạn ngữ "Nếu nó giống như vịt và ruồi như vịt, nó cũng có thể là một con vịt" (tốt, đó không phải là câu ngạn ngữ thực sự nhưng tôi có ý chính của nó)

Một nơi bạn sẽ thấy điều này rất nhiều trong thư viện chuẩn, với bất kỳ chức năng nào xử lý đầu vào hoặc đầu ra của tệp. Thay vì yêu cầu đối tượng thực tế file, họ sẽ thực hiện bất kỳ điều gì thực hiện phương thức read() hoặc readline() (tùy thuộc vào chức năng) hoặc write() để viết. Trên thực tế, bạn thường thấy điều này trong tài liệu, ví dụ: với tokenize.generate_tokens, mà tôi chỉ tình cờ được xem xét trước ngày hôm nay:

Các máy phát điện generate_tokens() đòi hỏi một đối số, readline, mà phải là một đối tượng có thể được gọi mà cung cấp giao diện tương tự như phương pháp readline() được xây dựng trong đối tượng tệp (xem phần File Objects). Mỗi cuộc gọi đến hàm sẽ trả về một dòng đầu vào dưới dạng một chuỗi.

Điều này cho phép bạn sử dụng đối tượng StringIO (như tệp trong bộ nhớ) hoặc thứ gì đó khác thường như hộp thoại thay cho tệp thực.

Trong mã của riêng bạn, chỉ cần truy cập bất kỳ thuộc tính nào của đối tượng bạn cần và nếu đó là loại đối tượng không đúng, một trong các thuộc tính bạn cần sẽ không ở đó và nó sẽ ném một ngoại lệ.

+4

Thứ hai. Ngoài ra, hãy xem [EAFP] (http://docs.python.org/glossary.html#term-eafp): Dễ hỏi hơn sự tha thứ so với giấy phép. –

+0

điều này rất thú vị. Sau khi tất cả, chúng ta nên thưởng thức các tính năng pythons thay vì bảo vệ chúng. –

1

Tôi nghĩ rằng thực tiễn tốt là kiểm tra nhập cho loại. Giả sử rằng nếu bạn yêu cầu người dùng cung cấp cho một loại dữ liệu, họ có thể cung cấp cho bạn một loại dữ liệu khác, vì vậy bạn nên viết mã để bảo vệ chống lại điều này.

Tuy nhiên, có vẻ như lãng phí thời gian (cả viết và chạy chương trình) để kiểm tra loại đầu vào mà chương trình tạo độc lập với đầu vào. Như trong một ngôn ngữ được đánh máy mạnh, việc kiểm tra loại không quan trọng để bảo vệ chống lại lỗi lập trình . Vì vậy, về cơ bản, kiểm tra đầu vào nhưng không có gì khác để mã có thể chạy trơn tru và người dùng không cần phải tự hỏi tại sao họ có một ngoại lệ chứ không phải là kết quả.

+1

Đây có lẽ là lời khuyên tốt về các ngôn ngữ khác, nhưng nó không phải là thực hành phổ biến trong Python. Xem câu trả lời của David ở trên. –

+1

nhận xét rất quan trọng. tiếp tục kiểm tra INPUT. sự khác biệt giữa lỗi lập trình viên và lỗi người dùng là rất quan trọng. cảm ơn. –

+0

Tôi không chắc chắn; Tôi đã học python từ MIT OCW và các giáo sư tại MIT luôn nói về "mã hóa phòng thủ", ngay cả trong python –

0

Nếu lựa chọn thay thế cho kiểm tra kiểu là một lựa chọn khác có xử lý ngoại lệ, bạn nên xem vịt gõ một tầng lên, hỗ trợ nhiều đối tượng với các phương thức bạn yêu cầu từ đầu vào và làm việc bên trong thử. Sau đó, bạn có thể ngoại trừ (và ngoại trừ càng cụ thể càng tốt). Kết quả cuối cùng sẽ không giống với những gì bạn có ở đó, nhưng linh hoạt hơn và Pythonic.

Mọi thứ khác cần được nói về câu hỏi thực tế, cho dù đó là thực tiễn phổ biến/tốt hay không, tôi nghĩ rằng đã được trả lời một cách xuất sắc bởi David.

0

Tôi đồng ý với một số câu trả lời ở trên, trong đó tôi thường không bao giờ kiểm tra loại từ chức năng này sang hàm khác.

Tuy nhiên, như người khác đã đề cập, mọi nội dung được chấp nhận từ người dùng nên được chọn và đối với những thứ như thế này tôi sử dụng cụm từ thông dụng. Điều tuyệt vời về việc sử dụng cụm từ thông dụng để xác thực người dùng là không chỉ bạn có thể xác minh rằng dữ liệu có định dạng đúng, nhưng bạn có thể phân tích cú pháp đầu vào thành một biểu mẫu thuận tiện hơn, như chuỗi thành từ điển.

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