มีวิธีส่งผ่านพารามิเตอร์ทางเลือกไปยังฟังก์ชันหรือไม่?


135

มีวิธีใน Python หรือไม่ในการส่งผ่านพารามิเตอร์ที่เป็นทางเลือกไปยังฟังก์ชันในขณะที่เรียกใช้และในนิยามฟังก์ชันจะมีโค้ดบางส่วนตาม "เฉพาะในกรณีที่ส่งผ่านพารามิเตอร์ที่เป็นทางเลือก"

คำตอบ:


115

งูหลาม 2 เอกสาร7.6 คำจำกัดความของฟังก์ชันช่วยให้คุณสามารถตรวจสอบได้ว่าผู้เรียกใช้พารามิเตอร์เสริมหรือไม่

*ครั้งแรกที่คุณสามารถใช้ไวยากรณ์พิเศษพารามิเตอร์อย่างเป็นทางการ หากนิยามฟังก์ชันมีพารามิเตอร์ที่เป็นทางการนำหน้าด้วยค่าเดียว*Python จะเติมพารามิเตอร์นั้นด้วยพารามิเตอร์ตำแหน่งใด ๆ ที่ไม่ได้จับคู่โดยนำหน้าพารามิเตอร์ที่เป็นทางการ (เป็นทูเพิล) หากนิยามฟังก์ชันมีพารามิเตอร์ที่เป็นทางการนำหน้าด้วย**Python จะเติมพารามิเตอร์นั้นด้วยพารามิเตอร์คีย์เวิร์ดใด ๆ ที่ไม่ได้จับคู่โดยนำหน้าพารามิเตอร์ที่เป็นทางการ (เป็นคำสั่ง) การใช้งานฟังก์ชันสามารถตรวจสอบเนื้อหาของพารามิเตอร์เหล่านี้สำหรับ "พารามิเตอร์ที่เป็นทางเลือก" ของการเรียงลำดับที่คุณต้องการ

ยกตัวอย่างเช่นนี่คือฟังก์ชั่นopt_funซึ่งจะใช้เวลาสองพารามิเตอร์ตำแหน่งx1และx2และรูปลักษณ์สำหรับพารามิเตอร์คำหลักอีกคนหนึ่งชื่อ "ตัวเลือก"

>>> def opt_fun(x1, x2, *positional_parameters, **keyword_parameters):
...     if ('optional' in keyword_parameters):
...         print 'optional parameter found, it is ', keyword_parameters['optional']
...     else:
...         print 'no optional parameter, sorry'
... 
>>> opt_fun(1, 2)
no optional parameter, sorry
>>> opt_fun(1,2, optional="yes")
optional parameter found, it is  yes
>>> opt_fun(1,2, another="yes")
no optional parameter, sorry

ประการที่สองคุณสามารถระบุค่าพารามิเตอร์เริ่มต้นของค่าบางค่าNoneที่ผู้โทรจะไม่ใช้ หากพารามิเตอร์มีค่าเริ่มต้นนี้คุณจะทราบว่าผู้เรียกไม่ได้ระบุพารามิเตอร์ หากพารามิเตอร์มีค่าที่ไม่ใช่ค่าเริ่มต้นแสดงว่ามาจากตัวเรียกใช้


7
positional_parametersคือทูเพิลและkeyword_parametersพจนานุกรม
Cees Timmerman

python แยกความแตกต่างformal parameters preceded by * (เรียกว่าอะไร?) จาก a keyword parameter? ตามที่ฉันเข้าใจแล้วพารามิเตอร์คำหลักจะถูกระบุโดยใช้ตัว=ดำเนินการในการเรียกฟังก์ชัน (ดังนั้นopt_fun(1,2, optional="yes")ให้อาร์กิวเมนต์คำหลัก "ใช่" สำหรับฟังก์ชันที่คาดการณ์ไว้ แต่ไม่จำเป็นต้องใช้พารามิเตอร์option)
มินห์ทราน

ในทางกลับกันฉันเข้าใจformal parameters preceded by * ว่าเป็นเพียง "อาร์กิวเมนต์ที่ระบุโดยผู้โทรซึ่งไม่สอดคล้องกับอาร์กิวเมนต์ตำแหน่งที่อยู่ก่อนอาร์กิวเมนต์คำหลักใด ๆ " ยกตัวอย่างเช่นในopt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018"), "blah"และ3.14เป็นforma arguments preceded by *เพราะมันอยู่ในระหว่างทั้งสองมีปากเสียงและตำแหน่งอาร์กิวเมนต์ที่ใช้ในการ=เข้าสู่ระบบ tuple ที่ส่งผลให้positional_parameterจะ duple ("blah", 3.14)นี้: ถูกต้องหรือไม่
Minh Tran

@MinhTran คำถามในความคิดเห็นไม่ใช่วิธีที่ดีที่สุดในการรับคำตอบใน Stack Overflow ควรคลิกปุ่ม "ถามคำถาม" สีน้ำเงินขนาดใหญ่และเขียนคำขอของคุณเป็น "คำถาม" ซึ่งผู้อื่นสามารถ "ตอบ" ได้ แต่เพื่อช่วยคุณ a) บันทึกที่ฉันเขียนว่า " parameter" not " parameters" for " preceded by *" ภาษาอนุญาตให้ใช้ภาษาเดียว*identifierในรายการพารามิเตอร์ ข) อ่านdocs.python.org/2/reference/...ค) อ่านdocs.python.org/2/reference/expressions.html#calls ขออภัยไม่มีอักขระที่อนุญาตในความคิดเห็นนี้
Jim DeLaHunt

82
def my_func(mandatory_arg, optional_arg=100):
    print(mandatory_arg, optional_arg)

http://docs.python.org/2/tutorial/controlflow.html#default-argument-values

**kwargsฉันพบนี้อ่านได้มากขึ้นกว่าการใช้

ในการพิจารณาว่ามีการส่งอาร์กิวเมนต์หรือไม่ฉันใช้อ็อบเจ็กต์ยูทิลิตี้ที่กำหนดเองเป็นค่าเริ่มต้น:

MISSING = object()

def func(arg=MISSING):
    if arg is MISSING:
        ...

- ขอบคุณมีวิธีระบุค่าเริ่มต้นของพารามิเตอร์นี้เป็นตัวแปรอื่นในโค้ดหรือไม่?
user1795998

ใช่. default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...
warvariuc

สิ่งนี้ดูเหมือนจะแสดงวิธีใช้พารามิเตอร์ที่เป็นทางเลือก แต่ไม่ใช่วิธีทดสอบว่ามีการส่งผ่านหรือไม่ซึ่งเป็นสิ่งที่ OP กำลังถาม
Mawg กล่าวว่าคืนสถานะ Monica

4
ในกรณีส่วนใหญ่นี่เป็นโซลูชันที่ง่ายและตรงกว่าสำหรับ Jim's หากคุณตั้งค่าเริ่มต้นเป็นไม่มีคุณสามารถตรวจสอบได้ว่าผ่านพารามิเตอร์หรือไม่ กรณีเดียวที่วิธีแก้ปัญหาของจิมดีกว่าคือการแยกแยะระหว่างการส่งผ่านไม่มีเป็นข้อโต้แย้งและไม่ส่งผ่านข้อโต้แย้งเลย
Arnon Axelrod

19
def op(a=4,b=6):
    add = a+b
    print add

i)op() [o/p: will be (4+6)=10]
ii)op(99) [o/p: will be (99+6)=105]
iii)op(1,1) [o/p: will be (1+1)=2]
Note:
 If none or one parameter is passed the default passed parameter will be considered for the function. 

1
มีวิธีส่งผ่านเฉพาะพารามิเตอร์ที่สอง (b) และไม่ใช่พารามิเตอร์แรก (a) หรือไม่?
Djidiouf

4
@Djidiouf ใช่มีop(b=2)
Jürg Merlin Spaak

7

หากคุณต้องการกำหนดค่าเริ่มต้นให้กับพารามิเตอร์กำหนดค่าใน () เช่น (x = 10) แต่สิ่งสำคัญอันดับแรกควรเป็นอาร์กิวเมนต์บังคับตามด้วยค่าเริ่มต้น

เช่น.

(y, x = 10)

แต่

(x = 10, y) ผิด


ขอบคุณมีวิธีระบุค่าเริ่มต้นของพารามิเตอร์นี้เป็นตัวแปรอื่นในโค้ดหรือไม่
user1795998

ใช่คุณสามารถใช้สิ่งที่เรียกว่า*arg **kargเป็นอาร์กิวเมนต์ของฟังก์ชัน ค้นหาใน Google
sumit

สิ่งนี้ดูเหมือนจะแสดงวิธีใช้พารามิเตอร์ที่เป็นทางเลือก แต่ไม่ใช่วิธีทดสอบว่ามีการส่งผ่านหรือไม่ซึ่งเป็นสิ่งที่ OP กำลังถาม
Mawg กล่าวว่าคืนสถานะ Monica

2

คุณสามารถระบุค่าเริ่มต้นสำหรับอาร์กิวเมนต์ที่เป็นทางเลือกด้วยสิ่งที่จะไม่ส่งผ่านไปยังฟังก์ชันและตรวจสอบด้วยตัวisดำเนินการ:

class _NO_DEFAULT:
    def __repr__(self):return "<no default>"
_NO_DEFAULT = _NO_DEFAULT()

def func(optional= _NO_DEFAULT):
    if optional is _NO_DEFAULT:
        print("the optional argument was not passed")
    else:
        print("the optional argument was:",optional)

ตราบใดที่คุณไม่func(_NO_DEFAULT)สามารถตรวจสอบได้อย่างแม่นยำว่ามีการส่งผ่านข้อโต้แย้งหรือไม่และไม่เหมือนกับคำตอบที่ยอมรับคุณไม่ต้องกังวลเกี่ยวกับผลข้างเคียงของสัญกรณ์ **:

# these two work the same as using **
func()
func(optional=1)

# the optional argument can be positional or keyword unlike using **
func(1) 

#this correctly raises an error where as it would need to be explicitly checked when using **
func(invalid_arg=7)

_NO_DEFAULT = object()เพียงแค่ทำ
Aran-Fey

2 สายเสริมให้วิปัสสนาดีขึ้นก็คุ้ม ด้วยสิ่งนี้หากคุณเรียกใช้help(func)คุณจะได้รับความคิดที่ชัดเจนขึ้นว่าอาร์กิวเมนต์ถูกตีความอย่างไรหากไม่ผ่านอย่างชัดเจน
Tadhg McDonald-Jensen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.