2013-05-16 17 views
6

Giả sử tôi có hàm get_data có một số đối số từ khóa. Có một số cách tôi có thể làm điều nàySử dụng ** kwargs cả trong chức năng gọi và định nghĩa

def get_data(arg1, **kwargs): 
    print arg1, arg2, arg3, arg4 

arg1 = 1 
data['arg2'] = 2 
data['arg3'] = 3 
data['arg4'] = 4 

get_data(arg1, **data) 

Vì vậy, ý tưởng là để tránh gõ tên tham số trong cả hai gọi điện thoại chức năng và định nghĩa hàm. Tôi gọi hàm bằng từ điển làm đối số và các khóa của từ điển trở thành biến cục bộ của hàm và giá trị của chúng là giá trị từ điển

Tôi đã thử lỗi ở trên và nhận được số global name 'arg2' is not defined. Tôi hiểu rằng tôi có thể thay đổi locals() trong định nghĩa của get_data để có được hành vi mong muốn.

Vì vậy, mã của tôi sẽ trông như thế này

def get_data(arg1, kwargs): 
    locals().update(kwargs) 
    print arg1, arg2, arg3, arg4 

arg1 = 1 
data['arg2'] = 2 
data['arg3'] = 3 
data['arg4'] = 4 

get_data(arg1, data) 

và nó sẽ không làm việc quá. Ngoài ra tôi không thể đạt được hành vi mà không sử dụng locals()?

+0

Tôi đề nghị bạn hãy kiểm tra câu hỏi này http://stackoverflow.com/questions/3394835/args-and-kwargs –

+2

Không sửa đổi 'locals' , nó thậm chí không đảm bảo để làm việc tất cả các thời gian: http://docs.python.org/2/library/functions.html#locals – jamylak

+1

.. tại sao bạn thậm chí sẽ làm điều đó? Nếu bạn biết arg2, arg3, arg4 luôn Nếu không, thì ngay cả khi bạn có hành vi mong muốn, ngay khi bạn tham chiếu nói 'arg4' khi' dữ liệu' không định nghĩa 'arg4', nó sẽ làm tăng một NameError, nó thậm chí sẽ không in bất kỳ dữ liệu nào, nó sẽ chỉ gây ra lỗi. – kampu

Trả lời

11

**kwargs là từ điển đơn giản. Hãy thử điều này:

def get_data(arg1, **kwargs): 
    print arg1, kwargs['arg2'], kwargs['arg3'], kwargs['arg4'] 

Ngoài ra, hãy kiểm tra tài liệu trên keyword arguments.

3

Nếu chúng ta xem xét ví dụ của bạn:

def get_data(arg1, **kwargs): 
    print arg1, arg2, arg3, arg4 

Trong namespace get_data chức năng của bạn, có một biến có tên arg1, nhưng không có biến có tên arg2. do đó bạn không thể tiếp cận một hàm hoặc một biến không nằm trong không gian tên của bạn.

Thực tế, trong không gian tên của bạn; có một biến là arg1 và một đối tượng dictionary được gọi là kwargs. cho biết trình biên dịch python của bạn là kwargs là một từ điển và tất cả các giá trị trong từ điển đó sẽ được đánh giá như các tham số có tên trong định nghĩa hàm của bạn.

Cho phép hãy xem ví dụ sau:

def myFunc(**kwargs): 
    do something 

myFunc(key1='mykey', key2=2) 

khi bạn gọi myFunc với tên thông số key1key2, hành vi định nghĩa chức năng của bạn như

def myFunc(key1=None, key2=None): 

nhưng với một ngoại lệ! kể từ myFunc không có tham số được đặt tên, trình biên dịch không biết cách xử lý chúng trực tiếp vì bạn có thể chuyển bất kỳ tham số nào được đặt tên cho hàm của bạn.

Vì vậy, chức năng của bạn chấp nhận những thông số được đặt tên trong một cuốn từ điển như bạn gọi chức năng của bạn:

myFunc({key1:'mykey', key2:2}) 

như vậy, định nghĩa chức năng của bạn có được những thông số trong một cuốn từ điển.**kwargs định nghĩa từ điển của bạn trong thời điểm đó, mà cũng nói với trình biên dịch rằng bất kỳ thông số được đặt tên sẽ được chấp nhận (bởi sự giúp đỡ của ** dấu hiệu trước khi kwargs)

def myFunc(**kwargs): 
    print kwargs 

sẽ in

{key1:'mykey', key2:2} 

Vì vậy, trong ví dụ của bạn , bạn có thể sử dụng kwargs như một từ điển;

def myFunc(**kwargs): 
    kwargs['arg2'] 
    kwargs.get('arg3') 

Tôi hy vọng nó không phải là rất phức tạp (:

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