2010-10-14 43 views
7

Tôi đang tạo một ứng dụng wxpython mà tôi sẽ biên dịch với các tiện ích đóng băng khác nhau để tạo một tệp thực thi cho nhiều nền tảng.Python - Tạo một hệ thống "tập lệnh"

chương trình sẽ là một editer bản đồ cho một gạch dựa trên công cụ trò chơi

trong ứng dụng này tôi muốn cung cấp một hệ thống kịch bản để người dùng nâng cao có thể điều chỉnh hành vi của các chương trình như thay đổi dữ liệu dự án, xuất khẩu dự án sang một định dạng khác ect.

Tôi muốn hệ thống hoạt động như vậy.

người dùng sẽ đặt tập lệnh python mà họ muốn chạy vào hộp văn bản được tạo kiểu và sau đó nhấn nút để thực thi tập lệnh.

Tôi rất hài lòng với điều này cho đến nay thats tất cả những thứ thực sự đơn giản. lấy kịch bản từ các văn bản hộp như là một chuỗi biên dịch nó vào một đối tượng cá tuyết với chức năng biên dịch sẵn có() sau đó thực thi kịch bản với một Statment exec

script = textbox.text #bla bla store the string 
code = compile(script, "script", "exec") #make the code object 
eval(code, globals()) 

điều là, tôi muốn chắc chắn rằng tính năng này không thể gây ra bất kỳ lỗi hoặc lỗi nào
nói nếu có câu lệnh nhập trong tập lệnh. điều này sẽ gây ra bất kỳ vấn đề nào có tính đến mã đã được biên dịch với một cái gì đó như py2exe hoặc py2app?
làm cách nào để đảm bảo rằng người dùng không thể phá vỡ phần quan trọng của chương trình như sửa đổi một phần GUI trong khi vẫn cho phép họ sửa đổi dữ liệu dự án (dữ liệu được giữ trong thuộc tính chung trong mô-đun riêng của nó)? Tôi nghĩ rằng điều này có nghĩa là sửa đổi các dict globals được chuyển đến hàm eval.
làm cách nào để đảm bảo rằng eval này không thể khiến chương trình bị treo do vòng lặp dài hoặc vô hạn? làm cách nào để đảm bảo rằng lỗi được nêu trong mã của người dùng không thể làm hỏng toàn bộ ứng dụng?

về cơ bản, làm cách nào để tránh tất cả các sự cố có thể phát sinh khi cho phép người dùng chạy mã của riêng họ?

EDIT: Liên quan đến câu trả lời cho

Tôi không cảm thấy giống như bất kỳ các câu trả lời cho đến nay đã thực sự trả lời câu hỏi của tôi vâng họ có được trong phần trả lời nhưng không hoàn toàn. Tôi biết rõ rằng không thể dừng hoàn toàn mã không an toàn. mọi người chỉ là quá thông minh đối với một người (hoặc thậm chí là một teem) để nghĩ về tất cả các cách để có được xung quanh một hệ thống an ninh và ngăn chặn chúng.

thực ra tôi không thực sự quan tâm nếu họ làm. Tôi lo lắng hơn về một số người vô ý phá vỡ một cái gì đó mà họ không biết. nếu một số người thực sự muốn họ có thể xé ứng dụng thành từng mảnh với chức năng kịch bản, nhưng tôi không thể quan tâm ít hơn. nó sẽ là ví dụ của họ và tất cả các vấn đề mà họ tạo ra sẽ biến mất khi họ khởi động lại ứng dụng trừ khi họ đã nhầm lẫn với các tệp trên HD. Tôi muốn ngăn chặn các vấn đề phát sinh khi người dùng liều một cái gì đó ngu ngốc.
những thứ như IOError's, SystaxErrors, InfiniteLoopErrors ect.

bây giờ phần về phạm vi đã được trả lời. Bây giờ tôi hiểu cách xác định chức năng và globals nào có thể được truy cập từ hàm nhưng có cách nào để đảm bảo rằng việc thực thi mã của chúng có thể bị dừng lại nếu quá trình này mất quá nhiều thời gian?
một hệ thống luồng màu xanh lá cây có lẽ?(Màu xanh lá cây vì nó sẽ là eval để làm cho người dùng lo lắng về an toàn thread)

cũng nếu một người dùng sử dụng một tuyên bố import module để nạp một module từ ngay cả những thư viện mặc định mà không được sử dụng trong phần còn lại của lớp. điều này có thể gây ra sự cố với ứng dụng đang bị đóng băng bởi Py2exe, Py2app hoặc Freeze không? nếu họ gọi phương thức bên ngoài của thư viện chuẩn thì sao? nó sẽ là đủ mà các phương thức có mặt trong cùng một thư mục như thực thi đông lạnh?

Tôi muốn nhận được những câu trả lời này với việc tạo ra một câu hỏi mới nhưng tôi sẽ làm gì nếu tôi phải.

+0

Đánh giá thực tế là không thể thực hiện được imo hoàn toàn an toàn (nhưng đó không phải là lĩnh vực chuyên môn chính của tôi, tôi có thể đang nói chuyện với tôi). Tại sao không đi theo cách phát triển một API với cấu trúc trình cắm thêm cho điều này, nếu phạm vi bảo mật/tích hợp và chức năng là một mối quan tâm? –

+0

Hey, ít nhất nó không phải là 'exec'. – nmichaels

+0

Ít nhất, hãy nhận ra rằng đây là một trong những trường hợp thực sự hiếm hoi mà một gotta-catch-'em-all 'ngoại trừ: 'có ý nghĩa và áp dụng nó. Không cần phải sụp đổ toàn bộ ứng dụng vì người dùng tương đối mới với python đã bỏ lỡ một không gian. 1 và được yêu thích, tôi mong muốn kết hợp một REPL Python vào một ứng dụng của tôi nữa. – delnan

Trả lời

5

Câu trả lời dễ dàng: không.

Bạn có thể cấm các từ khóa nhất định (import) và các hoạt động và truy cập vào một số cấu trúc dữ liệu nhất định, nhưng cuối cùng bạn đang cung cấp cho người dùng quyền lực của mình một chút năng lượng. Vì điều này là dành cho một khách hàng phong phú chạy trên máy của người dùng, một người dùng độc hại có thể gặp sự cố hoặc thậm chí làm hỏng toàn bộ ứng dụng nếu họ thực sự cảm thấy thích nó. Nhưng đó là trường hợp của họ để sụp đổ. Viết tài liệu tốt và cho mọi người biết những gì không được chạm vào.

Điều đó nói rằng, tôi đã thực hiện việc này cho các ứng dụng web mà thực thi đầu vào người sử dụng và có, gọi eval như thế này:

eval(code, {"__builtins__":None}, {safe_functions}) 

nơi safe_functions là một từ điển chứa {"name": func} cặp loại chức năng bạn muốn người dùng của bạn có thể truy cập. Nếu có một số cấu trúc dữ liệu cần thiết mà bạn đang dương người dùng của bạn sẽ không bao giờ muốn chọc vào, chỉ cần bật nó ra khỏi globals trước khi đi qua chúng trong.

Ngẫu nhiên, Guido giải quyết vấn đề này trên blog của mình một thời gian trước đây. Tôi sẽ xem nếu tôi có thể tìm thấy nó.

Edit:found.

+0

"Câu trả lời dễ dàng: không." -Hà! đúng, tuy nhiên Đó là ý định của tôi trong việc tạo ra ứng dụng này để 1) tìm hiểu rất nhiều về python 2) tạo ra một ứng dụng mà thực sự có thể được sử dụng hiệu quả và mạnh mẽ. Tôi biết rằng hoàn toàn ngăn chặn người dùng phá vỡ một cái gì đó là không thể ngắn không cho phép họ chạy mã. nhưng chắc chắn nó có thể ngăn chặn các ứng dụng từ bị rơi nếu có mã tăng một lỗi mà họ đã không mong đợi trong hoàn cảnh họ không lường trước được. hoặc ngừng việc thực thi mã của họ nếu nó bị treo vì có điều gì đó không ổn. – Ryex

+0

Tôi có nghĩa là không hạn chế nó. Việc thêm chức năng tạo kịch bản là rất tốt cho người dùng có quyền lực, nhưng hãy báo trước rằng họ có thể phá vỡ nội dung khá phổ biến. – nmichaels

+1

Bạn có thể nhúng một cái gì đó như PyV8 thay vào đó (http://code.google.com/p/pyv8/), vì vậy bạn vẫn sẽ nhận được một ngôn ngữ lập trình đầy đủ, nhưng bạn phải cung cấp các hình cầu của riêng bạn và thêm một phụ thuộc phụ . –

1

ngắn Trả lời: Không

bài viết liên quan khác:

Không dễ tạo lưới an toàn. Các chi tiết quá nhiều và hacks thông minh là xung quanh:

Mở mục tiêu thiết kế của bạn:

Có vẻ như bạn đang cố gắng để xây dựng một hệ thống có thể mở rộng bằng cách cung cấp người dùng sửa đổi rất nhiều hành vi và logic.

Tùy chọn dễ nhất là yêu cầu họ viết kịch bản mà bạn có thể đánh giá (eval) trong khi chạy chương trình.

Bao giờ, một thiết kế mô tả, giám sát tính linh hoạt và cung cấp cơ chế tập lệnh thông qua các sơ đồ thiết kế khác nhau, từ cấu hình, plugin đến khả năng viết kịch bản, vv. Nó cũng an toàn hơn.

+0

Tôi hoàn toàn không đồng ý hoặc không đồng ý với phần cuối cùng. Một ứng dụng cho phép bản thân kịch bản của tôi sẽ giúp tôi làm việc hiệu quả hơn nhiều (oh, tất cả những X đó sẽ là Y ... tốt, tôi sẽ viết một vòng lặp sửa lỗi). Đó là một giải pháp rẻ tiền để giúp người dùng nâng cao. Nhưng tất nhiên cấu hình "thực" và plugin rất tiện lợi và cũng có thể truy cập được cho nhiều người dùng hơn. – delnan

+0

@delnan: Tôi hoàn toàn đồng ý với bạn. Nhưng đối với hầu hết người dùng, nó vẫn hữu ích hơn cung cấp khả năng mở rộng thông qua plugin, API tập lệnh, v.v.Công việc mà người dùng nâng cao sẽ làm sẽ rất sáng tạo nhưng một phương tiện trống thường không hoạt động tốt với hầu hết người dùng. – pyfunc

0

Tôi khuyên bạn nên cung cấp một số loại API trình cắm và cho phép người dùng cung cấp các trình cắm dưới dạng tệp văn bản. Sau đó, bạn có thể nhập chúng dưới dạng mô-đun vào không gian tên riêng của chúng, bắt lỗi cú pháp trong quá trình và gọi các hàm khác nhau được xác định trong mô-đun trình cắm thêm, lại kiểm tra lỗi. Bạn có thể cung cấp một mô-đun API để xác định các hàm/lớp từ chương trình của bạn mà mô-đun trình cắm thêm có quyền truy cập. Điều đó mang lại cho bạn sự tự do để thực hiện các thay đổi đối với kiến ​​trúc của ứng dụng mà không phá vỡ các trình cắm thêm vì bạn chỉ có thể điều chỉnh mô-đun API để hiển thị các chức năng theo cùng một cách.

0

Nếu bạn có tùy chọn chuyển sang Tkinter, bạn có thể sử dụng trình thông dịch tcl đi kèm để xử lý tập lệnh của mình. Cho rằng vấn đề bạn có thể có thể làm điều đó với một ứng dụng wxpython nếu bạn không bắt đầu vòng lặp sự kiện tk; chỉ cần sử dụng trình thông dịch tcl mà không cần tạo bất kỳ cửa sổ nào.

Vì trình thông dịch tcl là một điều riêng biệt nên gần như không thể phá vỡ trình thông dịch python nếu bạn cẩn thận về những lệnh bạn tiếp xúc với tcl. Plus, tcl làm cho việc tạo DSL rất dễ dàng.

Python - ngôn ngữ kịch bản duy nhất có công cụ tạo tập lệnh tích hợp :-).

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