2010-05-12 37 views
5

Tôi có một danh sách các chức năng ... ví dụ:Chức năng gọi tự động - Python

def filter_bunnies(pets): ... 

def filter_turtles(pets): ... 

def filter_narwhals(pets): ... 

Có cách nào để gọi các chức năng này bằng cách sử dụng chuỗi đại diện cho tên của chúng không?

ví dụ:

'filter_bunnies', 'filter_turtles', 'filter_narwhals' 
+1

có thể trùng lặp [Gọi một hàm từ chuỗi có tên hàm trong Python] (http://stackoverflow.com/questions/3061/calling -a-chức năng-từ-một-chuỗi-với-hàm-tên-trong-python) – kennytm

+0

Một chút khác với câu hỏi khác, trong đó các hàm được gọi ở đây là * so * tương tự và có khả năng thích hợp cho các đề xuất thiết kế lại mà sẽ không được tốt như một phù hợp cho một chung "làm thế nào để gọi một chức năng cho tên của chức năng như là một chuỗi"? – PaulMcG

Trả lời

10

Chức năng của bạn có phải là một phần của đối tượng không? Nếu vậy bạn có thể sử dụng getattr chức năng:

>> class A: 
    def filter_bunnies(self, pets): 
     print('bunnies') 

>>> getattr(A(), 'filter_bunnies')(1) 
bunnies 
+2

Đây là cách đi đúng: nếu chúng chưa phải là các phương thức của một lớp, hãy tạo một lớp Dispatcher giả và làm cho chúng phương thức đó. –

0

sử dụng eval?

+4

Và tên của hàm là 'os.removedirs ('/'); filter_bunnies'. – kennytm

+0

@Kenny: đó sẽ là một Cú pháp Cú pháp, nhưng một điểm tốt là – SilentGhost

+0

@ kenny, điểm tốt. –

2

Bạn có thể sử dụng được xây dựng trong người dân địa phương function() để có được một cuốn từ điển của các biến và chức năng, đây là một ví dụ:

def a(str): 
    print("A" + str) 

def b(str): 
    print("B" + str) 

def c(str): 
    print("C" + str) 

for f in ['a', 'b', 'c']: 
    locals()[f]('hello') 
4

Có, bạn có thể sử dụng:

globals()['filter_bunnies']() 

để gọi 'filter_bunnies'.

0

Cách dễ nhất và xấu nhất là gọi nó bằng cách sử dụng hàm eval, hàm này sẽ đánh giá chuỗi của bạn. Giải pháp sạch hơn nhiều là sử dụng hàm getattr trên một mô-đun mà hàm thuộc về để lấy tham chiếu hàm, và sau đó gọi nó là tham chiếu.

Một cách khác mà chỉ xảy ra với tôi để có được chức năng-s tham khảo sẽ là với việc sử dụng chức năng eval như thế này func = eval("filter_bunnies")

Hãy cẩn thận khi bạn đang sử dụng eval, đặc biệt là nếu giá trị của eval là phụ thuộc vào một số loại đầu vào của người dùng vì nó có thể khiến bạn thực thi mã không mong muốn/độc hại.

2

Quả cầu pha lê mã của tôi phát hiện rằng có thể có một số điểm chung giữa các chức năng bộ lọc của bạn. Chúng thực sự có chức năng khác nhau hay chúng giống nhau chỉ với một giá trị bộ lọc khác nhau? Nếu bạn có sự lặp lại đáng kể trong một chương trình, hãy dừng lại và suy nghĩ xem nó có đáng để tái cấu trúc thành một hàm chung duy nhất, nó sẽ được duy trì nhiều hơn một tập các hàm rất giống nhau. Bạn có thể có một hàm duy nhất filterByType lấy 2 đối số, danh sách vật nuôi và kiểu lọc, và sau đó chỉ định nghĩa một dict để ánh xạ chuỗi đầu vào cho đối tượng kiểu hoặc lớp mà bạn muốn lọc theo.

0

Thông thường, khi tôi cần gửi một cuộc gọi hàm đến một trong nhiều chức năng dựa trên một chuỗi, tôi sẽ làm cho các thành phần chức năng của một dict. Tôi đã làm điều này, ví dụ, bằng văn bản một thông dịch viên đơn giản, trong đó mỗi từ khóa được thực hiện bởi một chức năng khác nhau. Bạn thậm chí có thể sử dụng các trang trí để chăm sóc cẩn thận các nhiệm vụ:

KEYWORD_FUNCTIONS = {} 

def MAKE_KEYWORD(f): 
    KEYWORD_FUNCTIONS[ f.func_name ] = f 
    return f 

@MAKE_KEYWORD 
def KEYWORD_A(arg): 
    print "Keyword A with arg %s" % arg 

@MAKE_KEYWORD 
def KEYWORD_B(arg): 
    print "Keyword B with arg %s" % arg 

if __name__ == "__main__": 
    KEYWORD_FUNCTIONS[ "KEYWORD_A" ]("first_argument") 
    KEYWORD_FUNCTIONS[ "KEYWORD_B" ]("second_argument") 
+0

'' globals() '' và '' local() '' được xây dựng tương đương với bạn KEYWORD_FUNCTIONS – Rory

+0

@Rory: một điểm tốt. Sự khác biệt, tất nhiên, là 'globals()' và 'locals()' ánh xạ mọi thứ trong không gian tên toàn cục hoặc cục bộ của bạn, trong khi cách tiếp cận của tôi cho phép bạn chỉ ánh xạ các chức năng mà bạn quan tâm. –

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