2009-08-28 25 views
49

Tôi đang giải một câu đố bằng cách sử dụng python và tùy thuộc vào câu đố nào tôi đang giải quyết, tôi sẽ phải sử dụng một bộ quy tắc đặc biệt. Làm thế nào tôi có thể chuyển một hàm vào một hàm khác trong Python?Python - Chuyển hàm vào hàm khác

Ví dụ

def Game(listA, listB, rules): 
    if rules == True: 
     do... 
    else: 
     do... 

def Rule1(v): 
    if "variable_name1" in v: 
     return False 
    elif "variable_name2" in v: 
     return False 
    else: 
     return True 

def Rule2(v): 
    if "variable_name3" and "variable_name4" in v: 
     return False 
    elif "variable_name4" and variable_name1 in v: 
     return False 
    else: 
     return True 

Đây chỉ là một mã giả và do đó không cụ thể nhưng tôi nhận được mã để biên dịch nhưng tôi cần phải biết làm thế nào để gọi hàm Game và cho dù đó là định nghĩa một cách chính xác kể từ khi quy tắc này sẽ được chuyển cho Rule1(v) hoặc Rule2(v).

Trả lời

96

Chỉ cần vượt qua nó trong giống như bất kỳ tham số khác:

def a(x): 
    return "a(%s)" % (x,) 

def b(f,x): 
    return f(x) 

print b(a,10) 
+30

chức năng là đối tượng hạng nhất trong python. bạn có thể vượt qua chúng xung quanh, bao gồm chúng trong dicts, danh sách, vv Chỉ cần không bao gồm dấu ngoặc đơn sau tên hàm. Ví dụ, đối với một hàm có tên 'myfunction':' myfunction' có nghĩa là chính hàm đó, 'myfunction()' có nghĩa là gọi hàm và nhận giá trị trả về của nó thay vào đó. – nosklo

+3

Tôi thích các ví dụ đơn giản, chúng chỉ có ý nghĩa !!! – mongotop

+0

Và nếu hàm là một phương thức trên một đối tượng và sử dụng một thuộc tính của đối tượng đó để thực hiện công việc của nó? – CpILL

13

chức năng Treat như biến trong chương trình của bạn vì vậy bạn chỉ có thể vượt qua họ để các chức năng khác một cách dễ dàng:

def test(): 
    print "test was invoked" 

def invoker(func): 
    func() 

invoker(test) # prints test was invoked 
+0

thực hiện điều này nếu test() nhận các đối số? @codeape ?? – Yasasvee

+0

Có. Trong ví dụ trên, hàm '' invoker'' sẽ cần cung cấp các đối số đó khi gọi hàm. – codeape

7

Chỉ cần vượt qua nó trong, như thế này:

Game(list_a, list_b, Rule1) 

và sau đó chức năng trò chơi của bạn có thể trông giống như thế này (vẫn là mã giả):

def Game(listA, listB, rules=None): 
    if rules: 
     # do something useful 
     # ... 
     result = rules(variable) # this is how you can call your rule 
    else: 
     # do something useful without rules 
7

Tên hàm có thể trở thành tên biến (và do đó được chuyển làm đối số) bằng cách thả dấu ngoặc đơn. Tên biến có thể trở thành tên hàm bằng cách thêm dấu ngoặc đơn.

Trong ví dụ của bạn, hãy đặt biến số rules thành một trong các hàm của bạn, bỏ dấu ngoặc đơn và đề cập đến đối số. Sau đó, trong hàm game(), hãy gọi rules(v) bằng dấu ngoặc đơn và thông số v.

if puzzle == type1: 
    rules = Rule1 
else: 
    rules = Rule2 

def Game(listA, listB, rules): 
    if rules(v) == True: 
     do... 
    else: 
     do... 
6

Một cách tiếp cận tổng quát

Đối với đi qua cả hai chức năng, và các tham số cho hàm (ví dụ bằng cách sử dụng thường xuyên lặp đi lặp lại tương tự cho các chức năng khác nhau) xem xét như sau (python2.x) ví dụ:

def test(a, b): 
    '''The function to pass''' 
    print a+b 

def looper(func, **kwargs): 
    '''A basic iteration function''' 
    for i in range(5): 
     # Our passed function with passed parameters 
     func(*tuple(value for _, value in kwargs.iteritems())) 

if __name__ == '__main__': 
    # This will print `3` five times 
    looper(test, a=1, b=2) 

Một số giải thích

  • tuple(i for i in (1, 2, 3)) là trình tạo bộ tuple, tạo bộ tuple từ các mục trong danh sách, bộ, tuple ...trong trường hợp của chúng tôi, các giá trị từ **kwargs
  • các * ở phía trước của tuple() sẽ giải nén nội dung của nó, một cách hiệu quả thông qua chúng như tham số cho hàm truyền
  • _ trong máy phát điện chỉ là một giữ chỗ cho key, vì chúng ta không sử dụng mà

Đối python3.x:

  • print(a+b) thay vì print a+b
  • kwargs.items() thay vì kwargs.iteritems()
Các vấn đề liên quan