วิธีตรวจสอบว่ามีคีย์ ** kwargs อยู่หรือไม่?


113

Python 3.2.3 มีแนวคิดบางอย่างที่ระบุไว้ที่นี่ซึ่งใช้ได้กับ var ปกติ แต่ดูเหมือนว่า ** kwargs จะเล่นตามกฎที่แตกต่างกัน ... เหตุใดจึงไม่ได้ผลและฉันจะตรวจสอบได้อย่างไรว่ามีคีย์ใน ** kwargs อยู่หรือไม่

if kwargs['errormessage']:
    print("It exists")

ฉันคิดว่ามันน่าจะใช้ได้ แต่มันไม่ได้ -

if errormessage in kwargs:
    print("yeah it's here")

ฉันเดาว่าเพราะ kwargs สามารถทำซ้ำได้หรือไม่? ฉันต้องทำซ้ำเพื่อตรวจสอบว่ามีคีย์ใดอยู่หรือไม่


4
ไม่มีกฎเกณฑ์พิเศษใด ๆ คุณลืมคำพูด
Lennart Regebro

คำตอบ:


169

คุณต้องการ

if 'errormessage' in kwargs:
    print("found it")

เพื่อให้ได้ค่าของ errormessage

if 'errormessage' in kwargs:
    print("errormessage equals " + kwargs.get("errormessage"))

วิธีนี้เป็นอีกหนึ่งเพียงkwargs dictตัวอย่างแรกของคุณif kwargs['errormessage']หมายถึง "รับค่าที่เกี่ยวข้องกับคีย์" errormessage "ใน kwargs จากนั้นตรวจสอบค่าบูล" ดังนั้นหากไม่มีคีย์ดังกล่าวคุณจะได้รับไฟล์KeyError.

ตัวอย่างที่สองของคุณif errormessage in kwargs:หมายถึง "if kwargsมีองค์ประกอบที่ตั้งชื่อโดย" errormessage"และเว้นแต่" errormessage"เป็นชื่อของตัวแปรคุณจะได้รับไฟล์NameError.

ฉันควรพูดถึงว่าพจนานุกรมยังมีวิธีการ.get()ที่ยอมรับพารามิเตอร์เริ่มต้น (ตัวเองเป็นค่าเริ่มต้นNone) เพื่อที่kwargs.get("errormessage")จะส่งคืนค่าหากมีคีย์นั้นอยู่และNoneอย่างอื่น ( kwargs.get("errormessage", 17)ทำในสิ่งที่คุณคิดว่าทำในทำนองเดียวกัน) เมื่อคุณไม่สนใจเกี่ยวกับความแตกต่างระหว่างคีย์ที่มีอยู่และมีNoneเป็นค่าหรือคีย์ที่ไม่มีอยู่สิ่งนี้จะเป็นประโยชน์


ขอบคุณสำหรับคำอธิบายเพิ่มเติม! ดีเสมอสำหรับผู้มาใหม่ python ในการรับข้อมูลพื้นฐานและตัวอย่างเพิ่มเติมเกี่ยวกับสิ่งที่เป็นไปได้และสิ่งที่ไม่เป็นไปได้ ในจิตวิญญาณนั้น: ฉันคิดว่าkwargs.get("errormessage", 17)อาจคืนค่าหรือ17ถ้าไม่มีข้อความผิดพลาด - แต่ฉันไม่แน่ใจ ถูกต้องหรือไม่
Honeybear

ใช่แล้ว พบว่าที่นี่ ขอบคุณ ... แค่อยากให้แน่ใจ
Honeybear

21

คำตอบของ DSM และ Tadeck ตอบคำถามของคุณโดยตรง

ในสคริปต์ของฉันฉันมักจะใช้ความสะดวกdict.pop()ในการจัดการกับข้อโต้แย้งที่เป็นทางเลือกและข้อโต้แย้งเพิ่มเติม นี่คือตัวอย่างของprint()Wrapper แบบธรรมดา:

def my_print(*args, **kwargs):
    prefix = kwargs.pop('prefix', '')
    print(prefix, *args, **kwargs)

จากนั้น:

>>> my_print('eggs')
 eggs
>>> my_print('eggs', prefix='spam')
spam eggs

ดังที่คุณเห็นหากprefixไม่มีอยู่ในkwargsค่าเริ่มต้น''(สตริงว่าง) จะถูกเก็บไว้ในprefixตัวแปรโลคัล หากมีการกำหนดค่าจะถูกใช้

โดยทั่วไปแล้วนี่เป็นสูตรที่กะทัดรัดและสามารถอ่านได้สำหรับการเขียน wrapper สำหรับฟังก์ชันประเภทใด ๆ : เพียงแค่ส่งผ่านอาร์กิวเมนต์ที่คุณไม่เข้าใจและไม่รู้ด้วยซ้ำว่ามีอยู่จริงหรือไม่ หากคุณผ่าน*argsและ**kwargsทำให้โค้ดของคุณช้าลงและต้องพิมพ์เพิ่มอีกเล็กน้อย แต่หากอินเทอร์เฟซของฟังก์ชันที่เรียก (ในกรณีนี้print) เปลี่ยนไปคุณไม่จำเป็นต้องเปลี่ยนรหัสของคุณ แนวทางนี้ช่วยลดเวลาในการพัฒนาในขณะที่รองรับการเปลี่ยนแปลงอินเทอร์เฟซทั้งหมด


prefixขอขอบคุณสำหรับการแสดงวิธีการกำหนดค่าเริ่มต้นให้
HBat

11

มันเป็นเพียงแค่นี้:

if 'errormessage' in kwargs:
    print("yeah it's here")

คุณต้องตรวจสอบว่าคีย์อยู่ในพจนานุกรมหรือไม่ ไวยากรณ์สำหรับสิ่งนั้นคือsome_key in some_dict( some_keyสิ่งที่แฮชได้อยู่ที่ไหนไม่จำเป็นต้องเป็นสตริง)

ความคิดคุณได้เชื่อมโยง ( ความคิดเหล่านี้ ) ที่มีตัวอย่างสำหรับการตรวจสอบถ้าสำคัญโดยเฉพาะมีอยู่ในพจนานุกรมกลับโดยและlocals() globals()ตัวอย่างของคุณคล้ายกันเนื่องจากคุณกำลังตรวจสอบการมีอยู่ของคีย์เฉพาะในkwargsพจนานุกรม (พจนานุกรมที่มีอาร์กิวเมนต์คำหลัก)


3

วิธีหนึ่งคือเพิ่มด้วยตัวเอง! อย่างไร? โดยการรวมเข้าkwargsกับค่าเริ่มต้นจำนวนมาก สิ่งนี้จะไม่เหมาะสมในทุกโอกาสตัวอย่างเช่นหากคุณไม่รู้จักกุญแจล่วงหน้า อย่างไรก็ตามหากเป็นเช่นนั้นนี่คือตัวอย่างง่ายๆ:

import sys

def myfunc(**kwargs):
    args = {'country':'England','town':'London',
            'currency':'Pound', 'language':'English'}

    diff = set(kwargs.keys()) - set(args.keys())
    if diff:
        print("Invalid args:",tuple(diff),file=sys.stderr)
        return

    args.update(kwargs)            
    print(args)

ค่าเริ่มต้นถูกกำหนดไว้ในพจนานุกรมargsซึ่งรวมถึงคีย์ทั้งหมดที่เราคาดหวัง ก่อนอื่นเราตรวจสอบว่ามีคีย์ที่ไม่คาดคิดใน kwargs หรือไม่ จากนั้นเราอัปเดตargsด้วยkwargsซึ่งจะแทนที่ค่าใหม่ใด ๆ ที่ผู้ใช้มีการตั้งค่า เราไม่จำเป็นต้องทดสอบว่าที่สำคัญที่มีอยู่ตอนนี้เราใช้เป็นพจนานุกรมโต้แย้งของเราและไม่จำเป็นต้องต่อไปของargskwargs


1

คุณสามารถค้นพบสิ่งเหล่านั้นได้ง่ายๆด้วยตัวเอง:

def hello(*args, **kwargs):
    print kwargs
    print type(kwargs)
    print dir(kwargs)

hello(what="world")

13
เอา "ง่าย" ออกแล้วเป็นคำตอบที่ดีกว่า หากเป็นเรื่องง่ายสำหรับทุกคนเราก็ไม่จำเป็นต้องมีไซต์นี้ การค้นหาตัวinดำเนินการในตัวเองไม่ใช่เรื่องง่ายหากคุณไม่เคยตั้งโปรแกรมและ / หรือเพิ่งเคยใช้ Python มาก่อน เป็นเพียงการบอกใบ้dict.get()และdict.setdefault()ความช่วยเหลือเท่านั้น
cfi

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.