"Đối số từ khóa" khác với đối số thông thường như thế nào? Không thể tất cả các đối số được thông qua name=value
thay vì sử dụng cú pháp vị trí?
"Đối số từ khóa" khác với đối số thông thường như thế nào? Không thể tất cả các đối số được thông qua name=value
thay vì sử dụng cú pháp vị trí?
Câu trả lời:
Có hai khái niệm liên quan, cả hai đều được gọi là " đối số từ khóa ".
Về phía gọi, đó là những gì các nhà bình luận khác đã đề cập, bạn có khả năng chỉ định một số đối số chức năng theo tên. Bạn phải đề cập đến chúng sau tất cả các đối số không có tên ( đối số vị trí ) và phải có các giá trị mặc định cho bất kỳ tham số nào không được đề cập ở tất cả.
Khái niệm khác nằm ở phía định nghĩa hàm: bạn có thể định nghĩa một hàm lấy tham số theo tên - và thậm chí bạn không phải chỉ định những tên đó là gì. Đây là các đối số từ khóa thuần túy và không thể được thông qua vị trí. Cú pháp là
def my_function(arg1, arg2, **kwargs)
Bất kỳ đối số từ khóa nào bạn chuyển vào hàm này sẽ được đặt vào một từ điển có tên kwargs
. Bạn có thể kiểm tra các khóa của từ điển này vào thời gian chạy, như thế này:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
kwargs
hoặc tôi có thể đổi tên thành sth. thích options
( def my_fuction(arg1, arg2, **options)
)?
kwargs
là quy ước khi không có tên thích hợp hơn
Có một tính năng ngôn ngữ cuối cùng trong đó sự khác biệt là quan trọng. Hãy xem xét các chức năng sau:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
Đối *positional
số sẽ lưu trữ tất cả các đối số vị trí được truyền vào foo()
, không giới hạn số lượng bạn có thể cung cấp.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
Đối **keywords
số sẽ lưu trữ bất kỳ đối số từ khóa:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
Và tất nhiên, bạn có thể sử dụng cả hai cùng một lúc:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
Các tính năng này hiếm khi được sử dụng, nhưng đôi khi chúng rất hữu ích và điều quan trọng là phải biết đối số nào là vị trí hoặc từ khóa.
*positional
và **keywords
nếu chúng ta thay đổi định nghĩa hàm như thế nào def foo(arg1, *positional, **keywords):
. Đây arg1
là vị trí và bắt buộc. Xin lưu ý rằng vị trí trong câu trả lời có nghĩa là số lượng tùy chọn và số lượng đối số vị trí.
foo(bar=True)
, bạn có thể nhận được các giá trị sử dụng bar = keywords.pop('bar')
tương tự như bar = keywords.pop('bar', None)
. Đối với giá trị mặc định, sử dụngbar = keywords.pop('bar', False)
Sử dụng các đối số từ khóa là điều tương tự như các đối số bình thường ngoại trừ thứ tự không quan trọng. Ví dụ, hai hàm gọi dưới đây giống nhau:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
Họ không có từ khóa trước họ. Thứ tự là quan trọng!
func(1,2,3, "foo")
Họ có từ khóa ở phía trước. Họ có thể theo thứ tự bất kỳ!
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
Bạn cũng nên biết rằng nếu bạn sử dụng các đối số mặc định và bỏ qua việc chèn các từ khóa, thì thứ tự sẽ có vấn đề!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
func("bar", 5)
? Và sau đó nói rằng hello
nhận được giá trị mặc định của nó 3
.
Có hai cách để gán giá trị đối số cho các tham số hàm, cả hai đều được sử dụng.
Theo vị trí. Đối số vị trí không có từ khóa và được chỉ định trước.
Theo từ khóa. Đối số từ khóa có từ khóa và được chỉ định thứ hai, sau đối số vị trí.
Lưu ý rằng bạn có tùy chọn để sử dụng đối số vị trí.
Nếu bạn không sử dụng đối số vị trí, thì - có - mọi thứ bạn viết hóa ra là đối số từ khóa.
Khi bạn gọi một chức năng, bạn đưa ra quyết định sử dụng vị trí hoặc từ khóa hoặc hỗn hợp. Bạn có thể chọn làm tất cả các từ khóa nếu bạn muốn. Một số người trong chúng ta không đưa ra lựa chọn này và sử dụng các đối số vị trí.
Tôi ngạc nhiên rằng dường như không ai chỉ ra rằng người ta có thể vượt qua một từ điển các tham số đối số được khóa, đáp ứng các tham số chính thức, như vậy.
>>> def func(a='a', b='b', c='c', **kwargs):
... print 'a:%s, b:%s, c:%s' % (a, b, c)
...
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>>
, **kwargs
. Điều đó sẽ chứng minh rằng ngay cả một func def đơn giản, với một số tham số cố định, có thể được cung cấp một từ điển. Đó là, nó không yêu cầu bất cứ điều gì lạ mắt trong định nghĩa. THÌ bạn có thể thêm một ví dụ thứ hai, VỚI ** kwargs trong định nghĩa và chỉ ra cách các mục EXTRA trong từ điển có sẵn thông qua đó.
print 'a:%s, b:%s, c:%s' % (a, b, c)
đưa ra lỗi cú pháp, tuy nhiên print('a:%s, b:%s, c:%s' % (a, b, c))
hoạt động. Một cái gì đó với phiên bản Python? Dù sao cũng cảm ơn vì sự sáng suốt này, cho đến bây giờ tôi vẫn đang sử dụng thứ đồ sộ hơnprint('a:{}, b:{}, c:{}'.format(a, b, c))
Sử dụng Python 3, bạn có thể có cả đối số từ khóa bắt buộc và không bắt buộc :
Tùy chọn : (giá trị mặc định được xác định cho param 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
Bắt buộc (không có giá trị mặc định được xác định cho param 'b'):
def func2(a, *, b):
...
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`
Điều này có thể giúp ích trong trường hợp bạn có nhiều đối số tương tự cạnh nhau, đặc biệt nếu chúng cùng loại, trong trường hợp đó tôi thích sử dụng các đối số được đặt tên hoặc tôi tạo một lớp tùy chỉnh nếu các đối số thuộc về nhau.
Tôi ngạc nhiên không ai đề cập đến thực tế là bạn có thể kết hợp các đối số từ khóa và vị trí để làm những việc lén lút như thế này bằng cách sử dụng *args
và **kwargs
( từ trang web này ):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
Điều này cho phép bạn sử dụng các đối số từ khóa tùy ý có thể có các khóa bạn không muốn xác định trả trước.
Tôi đang tìm một ví dụ có kwargs mặc định bằng cách sử dụng chú thích kiểu:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
thí dụ:
>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
Chỉ cần bổ sung / thêm một cách để xác định giá trị mặc định của các đối số không được gán trong các từ khóa khi gọi hàm:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
gọi đây là:
print(func())
print(func(my_word='love'))
bạn sẽ nhận được:
default_msg
love
đọc thêm về *args
và **kwargs
trong python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3