2014-05-02 11 views
9

Với hàm bậc cao hơn có nhiều hàm làm đối số, hàm đó có thể chuyển đối số từ khóa tới đối số hàm như thế nào?Tách ** kwargs cho các chức năng khác nhau

dụ

def eat(food='eggs', how_much=1): 
    print(food * how_much) 


def parrot_is(state='dead'): 
    print("This parrot is %s." % state) 


def skit(*lines, **kwargs): 
    for line in lines: 
     line(**kwargs) 

skit(eat, parrot_is) # eggs \n This parrot is dead. 
skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot') # error 

state không phải là một arg từ khóa của eat vậy làm thế nào có thể Skit chỉ vượt qua args từ khóa có liên quan chức năng mà nó được gọi?

+4

Không nghi ngờ có nhiều cách để thực hiện điều này, nhưng tôi nghĩ rằng bạn đang tiếp cận này từ góc độ sai. Bạn sẽ làm gì nếu hai hàm của bạn lấy từ khóa arg có cùng tên và bạn muốn chuyển các giá trị khác nhau cho hai hàm này? Tốt nhất để chỉ cần vượt qua trong dicts của từ khóa args một cách rõ ràng. Mỗi đối số có khả năng sẽ là (nói) một tuple hai phần tử bao gồm một hàm và mệnh đề của từ khóa args. – Hammerite

+0

Đó có lẽ là giải pháp tốt nhất. – cheezsteak

Trả lời

8

Bạn có thể lọc từ điển kwargs dựa trên func_code.co_varnames của một hàm:

def skit(*lines, **kwargs): 
    for line in lines: 
     line(**{key: value for key, value in kwargs.iteritems() 
       if key in line.func_code.co_varnames}) 

Xem thêm: Can you list the keyword arguments a Python function receives?

+2

+1 hoặc sử dụng 'inspect.getargspec (line) .args'. –

+0

@A श wini च haudhary cảm ơn, điểm tốt, như luôn luôn hữu ích. Tôi cũng đã thêm một liên kết đến chuỗi liên quan. – alecxe

+0

Lợi ích của inspect.getargspec (func) .args trên line.func_code.co_varnames là gì? Sau đó, kiểm tra mô-đun chỉ cung cấp nhiều tùy chọn hơn mà chúng tôi không cần trong trường hợp này? – cheezsteak

6

Nếu bạn thêm **kwargs cho tất cả các định nghĩa, bạn có thể vượt qua toàn bộ rất nhiều:

def eat(food='eggs', how_much=1, **kwargs): 
    print(food * how_much) 


def parrot_is(state='dead', **kwargs): 
    print("This parrot is %s." % state) 


def skit(*lines, **kwargs): 
    for line in lines: 
     line(**kwargs) 

Mọi thứ trong số **kwargs cũng không phải là đối số từ khóa rõ ràng sẽ chỉ nhận được l eft trong kwargs và bị bỏ qua bằng ví dụ: eat.

Ví dụ:

>>> skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot') 
spamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspam 
This parrot is an ex-parrot. 
Các vấn đề liên quan