"อาร์กิวเมนต์คำหลัก" แตกต่างจากอาร์กิวเมนต์ปกติอย่างไร ไม่สามารถส่งอาร์กิวเมนต์ทั้งหมดname=value
แทนการใช้ไวยากรณ์ตำแหน่งได้หรือไม่
"อาร์กิวเมนต์คำหลัก" แตกต่างจากอาร์กิวเมนต์ปกติอย่างไร ไม่สามารถส่งอาร์กิวเมนต์ทั้งหมดname=value
แทนการใช้ไวยากรณ์ตำแหน่งได้หรือไม่
คำตอบ:
มีแนวคิดที่เกี่ยวข้องสองแนวคิดซึ่งเรียกว่า " อาร์กิวเมนต์ของคำหลัก "
ในด้านการโทรซึ่งเป็นสิ่งที่นักวิจารณ์คนอื่นพูดถึงคุณมีความสามารถในการระบุอาร์กิวเมนต์ของฟังก์ชันบางอย่างตามชื่อ คุณต้องพูดถึงพวกเขาหลังจากข้อโต้แย้งทั้งหมดโดยไม่มีชื่อ ( อาร์กิวเมนต์ตำแหน่ง ) และจะต้องมีค่าเริ่มต้นสำหรับพารามิเตอร์ใด ๆ ที่ไม่ได้กล่าวถึงเลย
แนวคิดอื่นอยู่ที่ด้านนิยามฟังก์ชัน: คุณสามารถกำหนดฟังก์ชันที่รับพารามิเตอร์ตามชื่อและคุณไม่จำเป็นต้องระบุชื่อเหล่านั้น นี่คืออาร์กิวเมนต์คำหลักที่แท้จริงและไม่สามารถส่งผ่านตำแหน่ง ไวยากรณ์คือ
def my_function(arg1, arg2, **kwargs)
ใดข้อโต้แย้งคำหลักkwargs
ที่คุณผ่านเข้าสู่ฟังก์ชั่นนี้จะถูกวางลงในพจนานุกรมชื่อ คุณสามารถตรวจสอบคีย์ของพจนานุกรมนี้ในเวลาทำงานเช่นนี้:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
kwargs
หรือฉันสามารถเปลี่ยนชื่อเป็น sth ชอบoptions
( def my_fuction(arg1, arg2, **options)
)?
kwargs
เป็นแบบแผนเมื่อไม่มีชื่อที่เหมาะสมกว่า
มีคุณลักษณะภาษาสุดท้ายหนึ่งที่ความแตกต่างเป็นสิ่งสำคัญ พิจารณาฟังก์ชั่นต่อไปนี้:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
*positional
อาร์กิวเมนต์จะเก็บทั้งหมดของการขัดแย้งตำแหน่งผ่านไปfoo()
โดยไม่มีการ จำกัด จำนวนที่คุณสามารถให้
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
**keywords
อาร์กิวเมนต์จะเก็บข้อโต้แย้งคำหลัก:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
และแน่นอนคุณสามารถใช้ทั้งสองอย่างในเวลาเดียวกัน:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
คุณสมบัติเหล่านี้ไม่ค่อยได้ใช้ แต่บางครั้งก็มีประโยชน์มากและเป็นสิ่งสำคัญที่จะต้องทราบว่าข้อโต้แย้งใดเป็นตำแหน่งหรือคำหลัก
*positional
และถ้าเราเปลี่ยนนิยามฟังก์ชั่นเช่น**keywords
def foo(arg1, *positional, **keywords):
นี่arg1
คือตำแหน่งและจำเป็น โปรดทราบว่าตำแหน่งในคำตอบหมายถึงตัวเลือกและจำนวนตัวแปรของการขัดแย้งตำแหน่ง
foo(bar=True)
คุณจะได้รับค่าใช้เช่นเดียวกับbar = keywords.pop('bar')
bar = keywords.pop('bar', None)
สำหรับค่าเริ่มต้นให้ใช้bar = keywords.pop('bar', False)
การใช้คำหลักอาร์กิวเมนต์เป็นสิ่งเดียวกับอาร์กิวเมนต์ปกติยกเว้นคำสั่งซื้อไม่สำคัญ ตัวอย่างเช่นการเรียกฟังก์ชันทั้งสองด้านล่างนี้จะเหมือนกัน:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
พวกเขาไม่มีคำหลักมาก่อน คำสั่งซื้อเป็นสิ่งสำคัญ!
func(1,2,3, "foo")
พวกเขามีคำหลักอยู่ข้างหน้า พวกเขาสามารถอยู่ในลำดับใด ๆ !
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
คุณควรทราบด้วยว่าหากคุณใช้อาร์กิวเมนต์เริ่มต้นและละเลยการแทรกคำหลักดังนั้นลำดับจะสำคัญ!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
func("bar", 5)
? แล้วบอกว่าhello
มันได้รับค่าเริ่มต้น3
เป็น
มีสองวิธีในการกำหนดค่าอาร์กิวเมนต์ให้กับพารามิเตอร์ฟังก์ชันซึ่งใช้ทั้งสองวิธี
ตามตำแหน่ง อาร์กิวเมนต์ตำแหน่งไม่ได้มีคำหลักและได้รับมอบหมายก่อน
โดยใช้คำสำคัญ อาร์กิวเมนต์คำหลักมีคำหลักและได้รับการกำหนดที่สองหลังจากอาร์กิวเมนต์ตำแหน่ง
โปรดทราบว่าคุณมีตัวเลือกในการใช้อาร์กิวเมนต์ตำแหน่ง
หากคุณไม่ได้ใช้อาร์กิวเมนต์ตำแหน่งแล้ว - ใช่ - ทุกสิ่งที่คุณเขียนกลายเป็นอาร์กิวเมนต์ของคำหลัก
เมื่อคุณเรียกใช้ฟังก์ชันคุณตัดสินใจใช้ตำแหน่งหรือคำหลักหรือส่วนผสม คุณสามารถเลือกที่จะทำคำหลักทั้งหมดหากคุณต้องการ พวกเราบางคนไม่ได้เลือกและใช้อาร์กิวเมนต์ตำแหน่ง
ฉันประหลาดใจที่ดูเหมือนว่าจะไม่มีใครชี้ให้เห็นว่าสามารถส่งพจนานุกรมพารามิเตอร์พารามิเตอร์ที่มีคีย์ซึ่งเป็นไปตามพารามิเตอร์ที่เป็นทางการเช่นนั้น
>>> 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
จุดของคุณจะเป็นที่ชัดเจนโดยไม่ต้อง นั่นจะแสดงให้เห็นว่าแม้แต่ฟังก์ชั่นการฟังก์ชั่นที่เรียบง่ายพร้อมพารามิเตอร์จำนวนคงที่ก็สามารถให้พจนานุกรมได้ นั่นคือมันไม่ต้องการอะไรแฟนซีในคำจำกัดความ จากนั้นคุณอาจเพิ่มตัวอย่างที่สองโดยมี ** kwargs ในคำจำกัดความและแสดงว่ารายการพิเศษในพจนานุกรมมีให้ผ่านทางนั้นได้อย่างไร
print 'a:%s, b:%s, c:%s' % (a, b, c)
ให้ข้อผิดพลาดทางไวยากรณ์ แต่ใช้print('a:%s, b:%s, c:%s' % (a, b, c))
งานได้ มีบางอย่างในเวอร์ชั่น Python ใช่ไหม ยังไงก็ตามขอบคุณสำหรับความเข้าใจนี้จนถึงตอนนี้ฉันใช้ clunky มากขึ้นprint('a:{}, b:{}, c:{}'.format(a, b, c))
การใช้Python 3คุณสามารถมีทั้งอาร์กิวเมนต์ที่จำเป็นและไม่จำเป็น:
ไม่บังคับ : (กำหนดค่าเริ่มต้นสำหรับพารามิเตอร์ 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
จำเป็น (ไม่ได้กำหนดค่าเริ่มต้นสำหรับพารามิเตอร์ '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'`
สิ่งนี้สามารถช่วยได้ในกรณีที่คุณมีข้อโต้แย้งที่คล้ายกันหลายตัวถัดจากกันโดยเฉพาะอย่างยิ่งถ้าเป็นประเภทเดียวกันในกรณีนั้นฉันชอบใช้อาร์กิวเมนต์ที่กำหนดชื่อหรือฉันสร้างคลาสแบบกำหนดเองหากมีอาร์กิวเมนต์ร่วมกัน
ฉันประหลาดใจที่ไม่มีใครพูดถึงความจริงที่ว่าคุณสามารถผสมอาร์กิวเมนต์ตำแหน่งและคำหลักเพื่อทำสิ่งที่ไม่น่าเชื่อเช่นนี้โดยใช้*args
และ**kwargs
( จากไซต์นี้ ):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
สิ่งนี้ช่วยให้คุณสามารถใช้อาร์กิวเมนต์คำหลักโดยพลการซึ่งอาจมีคีย์ที่คุณไม่ต้องการกำหนดล่วงหน้า
ฉันกำลังมองหาตัวอย่างที่มี kwargs เริ่มต้นโดยใช้คำอธิบายประกอบประเภท:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
ตัวอย่าง:
>>> 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 {}
เพียงแค่เพิ่ม / เพิ่มวิธีการกำหนดค่าเริ่มต้นของการขัดแย้งที่ไม่ได้กำหนดไว้ในคำสำคัญเมื่อเรียกใช้ฟังก์ชัน:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
เรียกสิ่งนี้โดย:
print(func())
print(func(my_word='love'))
คุณจะได้รับ:
default_msg
love
อ่านเพิ่มเติมเกี่ยวกับ*args
และ**kwargs
ในไพ ธ อน: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3