2009-06-22 27 views
14

Nền của tôi là C và C++. Tôi thích Python rất nhiều, nhưng có một khía cạnh của nó (và các ngôn ngữ thông dịch khác mà tôi đoán) thực sự khó làm việc khi bạn được sử dụng để biên dịch các ngôn ngữ.Làm cách nào để đảm bảo tất cả mã "biên dịch" của Python?

Khi tôi đã viết một cái gì đó bằng Python và đến thời điểm tôi có thể chạy nó, vẫn không đảm bảo rằng không có lỗi cụ thể về ngôn ngữ. Đối với tôi điều đó có nghĩa là tôi không thể chỉ dựa vào phòng thủ thời gian chạy của mình (kiểm tra nghiêm ngặt đầu vào, xác nhận, v.v.) để tránh sự cố, vì trong 6 tháng khi một số mã khác tốt đẹp cuối cùng được chạy, nó có thể bị lỗi do một số lỗi đánh máy ngu ngốc . Rõ ràng một hệ thống nên được kiểm tra đủ để đảm bảo tất cả các mã đã được chạy, nhưng hầu hết thời gian tôi sử dụng Python cho các tập lệnh nội bộ và các công cụ nhỏ, trong đó ofcourse không bao giờ nhận được sự quan tâm QA mà họ cần. Ngoài ra, một số mã đơn giản như vậy (nếu nền của bạn là C/C++) bạn biết nó sẽ hoạt động tốt miễn là nó biên dịch (ví dụ: các phương thức getter bên trong các lớp, thường là một sự trở về đơn giản của một biến thành viên). Vì vậy, câu hỏi của tôi là hiển nhiên - là có cách nào (với một công cụ đặc biệt hoặc một cái gì đó) tôi có thể chắc chắn rằng tất cả các mã trong kịch bản Python của tôi sẽ "biên dịch" và chạy?

+0

Đẹp ... Tôi là người C/C++ mới với Python, và vấn đề này đã khiến tôi thất vọng. Tôi chưa bao giờ nghĩ đến việc hỏi về một giải pháp, tôi không nghĩ là có thể tồn tại. –

Trả lời

21

Nhìn vào PyCheckerPyLint.

Dưới đây là ví dụ đầu ra từ pylint , kết quả từ các chương trình tầm thường:

print a 

Như bạn thấy, nó phát hiện các biến không xác định, mà py_compile sẽ không (cố tình)

in foo.py: 

************* Module foo 
C: 1: Black listed name "foo" 
C: 1: Missing docstring 
E: 1: Undefined variable 'a' 


... 

|error  |1  |1  |=   | 
. 10

dụ Trivial tại sao kiểm tra là không đủ tốt, ngay cả khi họ trang trải "mỗi dòng":

bar = "Foo" 
foo = "Bar" 
def baz(X): 
    return bar if X else fo0 

print baz(input("True or False: ")) 

EDIT: pychecker xử lý các ternary cho tôi:

Processing ternary... 
True or False: True 
Foo 

Warnings... 

ternary.py:6: No global (fo0) found 
ternary.py:8: Using input() is a security problem, consider using raw_input() 
+1

Đề xuất tốt về bộ kiểm tra và pylint. pyflakes cũng tốt vì nó rất nhanh, và phiên bản svn trunk sẽ bắt các biến cục bộ không sử dụng. Đối với thử nghiệm "mỗi dòng", tôi nghĩ bạn nên ít nhất là kiểm tra mọi "con đường". Điều đó có thể đã bắt được ví dụ của bạn. –

+1

Làm việc tuyệt vời Matthew, cảm ơn! – sharkin

+0

Không thể xác định (và sau đó kiểm tra) mọi đường dẫn logic có thể, bởi vì điều đó tương đương với vấn đề dừng (http://en.wikipedia.org/wiki/Code_coverage). –

1

Tôi nghĩ rằng những gì bạn đang tìm kiếm là phạm vi kiểm tra mã kiểm tra. Bạn muốn thêm các thử nghiệm vào tập lệnh của mình để đảm bảo tất cả các dòng mã của bạn, hoặc nhiều như bạn có thời gian, được kiểm tra. Thử nghiệm là một rất nhiều công việc, nhưng nếu bạn muốn các loại đảm bảo bạn đang yêu cầu, không có bữa ăn trưa miễn phí, xin lỗi :(.

+1

Anh ấy không tìm mã để vượt qua bài kiểm tra. Ông đã nói, "trong 6 tháng khi mã tốt đẹp khác cuối cùng đã được chạy, nó có thể chỉ đơn giản là crack do một số lỗi đánh máy." Kiểm tra xem liệu mã có "đúng" cho một số tập hợp đầu vào hữu hạn hay không, không phải là nó sử dụng cú pháp hợp lệ trong suốt (những gì OP muốn) –

+1

Nó sẽ không vượt qua nhiều bài kiểm tra nếu nó có lỗi chính tả. Nếu vùng phủ sóng của bạn chạm vào mọi dòng mã (không phải mọi đường dẫn logic), bạn sẽ chắc chắn hợp lý rằng nó sẽ hoạt động đáng tin cậy. –

+0

-1. Tôi xin lỗi Adam, câu hỏi cho thấy những nỗ lực QA như vậy là không thực tế, do đó câu trả lời là giúp đỡ rất ít. – sharkin

0

Mã của bạn thực sự được biên soạn khi bạn chạy nó, thời gian chạy Python sẽ phàn nàn nếu có lỗi cú pháp trong mã. So với các ngôn ngữ được biên dịch tĩnh như C/C++ hoặc Java, nó không kiểm tra xem tên và loại biến có đúng hay không - cho rằng bạn cần thực sự chạy mã (ví dụ: với các kiểm tra tự động).

+1

-1. Dường như thực sự có các công cụ xung quanh để phát hiện các lỗi như vậy, do đó không cần phải chạy mã để phát hiện chúng. – sharkin

1

Nếu bạn đang sử dụng Eclipse với Pydev làm IDE, nó có thể gắn cờ nhiều lỗi chính tả cho bạn với các quằn quại màu đỏ ngay lập tức và cũng có tích hợp Pylint. Ví dụ:

foo = 5 
print food 

sẽ được gắn cờ là "Biến không xác định: thực phẩm". Tất nhiên điều này không phải luôn luôn chính xác (có lẽ thực phẩm đã được định nghĩa trước đó bằng cách sử dụng setattr hoặc các kỹ thuật kỳ lạ khác), nhưng nó hoạt động tốt hầu hết thời gian.

Nói chung, bạn chỉ có thể phân tích tĩnh mã của bạn đến mức mã của bạn thực sự tĩnh; mã của bạn càng năng động, bạn càng thực sự cần kiểm tra tự động.

2

Những người khác đã đề cập đến các công cụ như PyLint là khá tốt, nhưng dài và ngắn của nó là nó chỉ đơn giản là không thể làm 100%. Trong thực tế, bạn có thể thậm chí không muốn làm điều đó. Một phần của lợi ích cho năng động của Python là bạn có thể làm những điều điên rồ như chèn tên vào phạm vi địa phương thông qua truy cập từ điển.

Điều sắp xảy ra là nếu bạn muốn có cách để bắt lỗi loại tại thời gian biên dịch, bạn không nên sử dụng Python. Lựa chọn ngôn ngữ luôn bao gồm một tập hợp các sự cân bằng. Nếu bạn chọn Python trên C, chỉ cần lưu ý rằng bạn đang giao dịch một hệ thống kiểu mạnh để phát triển nhanh hơn, thao tác chuỗi tốt hơn, v.v.

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