2017-06-15 11 views
5

Đây là bài đăng đầu tiên của tôi tại đây, vui lòng cho tôi biết nếu tôi làm sai. Tôi đã thử tìm kiếm câu trả lời hiện có, nhưng không chắc chắn nên tìm kiếm gì.Trích xuất mã để bản địa hóa nó trong một cuộc gọi lại

Hãy xem ví dụ đơn giản sau đây, mô-đun python có tên mymath.py chỉ sử dụng các hoạt động và mô-đun trăn tích hợp sẵn. Mô-đun tùy chỉnh này là di động, vì vậy, bất kỳ ai cũng có thể thực thi mã mà không cần cài đặt bất kỳ thứ gì khác ngoài mã chứng khoán.

# mymath.py 
import sys 

def minus(a, b): 
    return a-b 

def mult(a, b): 
    return a*b 

def div(a, b): 
    return a/b 

def plus(a, b): 
    return a+b 

def sum_series(int_list): 
    sum = 0 
    for i in int_list: 
     sum = plus(sum, i) 
    return sum 

def main(): 
    my_list = [2, 4, 6] 
    value = sum_series(my_list) 
    sys.stdout.write("your list total = {}".format(value)) 

Thông báo, main() chỉ gọi sum_series() nó sẽ gọi plus(). Các chức năng khác có thể được yêu cầu ở nơi khác trong cơ sở mã giả tưởng này, nhưng chúng tôi chỉ quan tâm đến main().

Bây giờ, tôi chỉ muốn sao chép mã nguồn có liên quan vào đối tượng khác dưới dạng chuỗi văn bản. Nói cách khác, thu thập main() và tất cả phụ thuộc của nó (đệ quy), dẫn đến một chuỗi mã thực thi.

giải pháp hiện tại của tôi:

import inspect 
import mymath 
# copy the source code in to the callback 
source = inspect.getsource(mymath) 
# then append a call to the main function 
source += "\nmain()" 

này hoạt động, tạo ra một bản sao cục bộ của các mô-đun như là một chuỗi có thể chạy main() mà không đòi hỏi một nhập khẩu mymath. Vấn đề là knob hiện đang cồng kềnh với tất cả các chức năng không sử dụng thêm, mặc dù có thể nhận bất kỳ thay đổi nào tôi thực hiện cho mymath.py bằng cách chạy lại giải pháp hiện tại của mình.

Vì vậy, câu hỏi là - là có một cách để làm điều tương đương với:

source = getFunctionSourcerRecursively(mymath.main) 
source += "\nmain()" 

dẫn đến source =

# mymath.py 
import sys 

def plus(a, b): 
    return a+b 

def sum_series(int_list): 
    sum = 0 
    for i in int_list: 
     sum = plus(sum, i) 
    return sum 

def main(): 
    my_list = [2, 4, 6] 
    sys.stdout.write("your list total = {}".format(sum_series(my_list))) 

main() 

Vì vậy, về cơ bản "nguồn" bây giờ chỉ chứa các mã liên quan và có thể di chuyển, không còn yêu cầu mọi người ngoại vi để cài đặt mymath nữa.

Nếu bạn tò mò, trường hợp thế giới thực của tôi liên quan đến việc sử dụng The Foundry Nuke (ứng dụng tổng hợp) có hệ thống gọi lại nội bộ có thể chạy mã khi các sự kiện gọi lại được kích hoạt trên knob (thuộc tính). Tôi muốn có thể chia sẻ các tệp Nuke đã lưu này (.nk hoặc .nknc) với khách hàng ngoại vi mà không yêu cầu họ sửa đổi hệ thống của họ.

+0

Điều này nghe có vẻ là một cách quá phức tạp và dễ bị lỗi khi thực hiện đóng gói. Đó là một vấn đề không tầm thường để xác định các phụ thuộc thời gian chạy của mã Python (xem xét, ví dụ, một nhánh có điều kiện dựa trên đầu ra của 'datetime.now()' hoặc 'random.random()'). Tại sao không chỉ viết 'setup.py' và mã phân phối theo cách thông thường, vì trứng hoặc bánh xe được cài đặt với' pip'? – wim

Trả lời

0

Bạn có thể thử informal interfaces (giao thức a.k.a.). Trong khi các giao thức hoạt động tốt trong nhiều trường hợp, có những tình huống mà giao diện không chính thức hoặc duck typing nói chung có thể gây nhầm lẫn. Ví dụ: AdditionMultiplication cả hai đều là mathFunc(). Nhưng chúng không giống nhau ngay cả khi chúng thực hiện cùng một giao diện/giao thức. Lớp cơ sở trừu tượng hoặc ABC có thể giúp giải quyết vấn đề này.

Khái niệm đằng sau ABC là đơn giản - người dùng xác định các lớp cơ sở trừu tượng trong tự nhiên. Chúng tôi định nghĩa các phương thức nhất định trên các lớp cơ sở như các phương thức trừu tượng. Vì vậy, bất kỳ đối tượng nào xuất phát từ các lớp cơ sở này đều buộc phải thực hiện các phương thức đó. Và vì chúng ta đang sử dụng các lớp cơ sở, nếu chúng ta thấy một đối tượng có lớp của chúng ta như là một lớp cơ sở, chúng ta có thể nói rằng đối tượng này thực hiện giao diện. Đó là bây giờ chúng ta có thể sử dụng các loại để cho biết nếu một đối tượng thực hiện một giao diện nhất định.

import mymath 

class MathClass(mymath.ABC): 
    @mymath.abstractmethod 
    def mathFunc(self): 
     pass 
Các vấn đề liên quan