Python ไม่มีการเปรียบเทียบ: ฉันควรใช้“ is” หรือ ==?


213

บรรณาธิการของฉันเตือนฉันเมื่อเปรียบเทียบแต่ไม่มีการเตือนล่วงหน้าเมื่อฉันใช้ my_var == Nonemy_var is None

ฉันทำการทดสอบใน Python shell และพิจารณาว่าทั้งคู่เป็นไวยากรณ์ที่ถูกต้อง แต่ตัวแก้ไขของฉันดูเหมือนจะบอกว่าmy_var is Noneเป็นที่ต้องการ

เป็นกรณีนี้หรือไม่และถ้าเป็นเช่นนั้นทำไม


7
PEP 8 กล่าวว่าบางแห่งที่คุณควรเปรียบเทียบกับการใช้ซิงเกิลตันis- python.org/dev/peps/pep-0008/#programming-recommendations
ความผันผวน

2
โปสเตอร์นั้นพูดถึง Python 3 และคำถามของฉันเกี่ยวกับ Python 2.x ฉันไม่แน่ใจว่านี่เป็นความแตกต่างใหญ่พอที่จะรับประกันทั้งสองที่เหลืออยู่ แต่ฉันแก้ไขคำถามเพื่อรวมไว้ในกรณี
Clay Wardell

2
ฉันไม่คิดว่าคำถามนี้ซ้ำซ้อนจริง ๆ อีกเรื่องหนึ่งเกี่ยวกับ == vs โดยทั่วไปอันนี้เกี่ยวกับไม่มีโดยเฉพาะ
IJ Kennedy

คำตอบ:


254

สรุป:

ใช้isเมื่อคุณต้องการตรวจสอบตัวตนของวัตถุ(เช่นการตรวจสอบเพื่อดูว่าvarมีNone) ใช้==เมื่อคุณต้องการตรวจสอบความเท่าเทียมกัน (เช่นvarเท่ากับ3หรือไม่)

คำอธิบาย:

คุณสามารถมีคลาสแบบกำหนดเองที่my_var == Noneจะส่งคืนTrue

เช่น:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isการตรวจสอบสำหรับวัตถุตัวตน มีเพียงวัตถุNoneเดียวดังนั้นเมื่อคุณทำmy_var is Noneคุณกำลังตรวจสอบว่าจริง ๆ แล้วพวกเขาเป็นวัตถุเดียวกัน (ไม่ใช่แค่วัตถุที่เทียบเท่า )

กล่าวอีกนัยหนึ่ง==คือการตรวจสอบความเท่าเทียมกัน (ซึ่งกำหนดจากวัตถุหนึ่งไปยังอีกวัตถุหนึ่ง) ในขณะที่isตรวจสอบตัวตนของวัตถุ:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
เมื่อไม่is Noneแตกต่างจาก== None?
เครื่องปั่น

11
@ Blender ในกรณีที่กล่าวถึง __eq__สามารถกำหนดได้ แต่อย่างใด แต่พฤติกรรมของisไม่สามารถเปลี่ยนแปลงได้อย่างง่ายดาย
Lev Levitsky

5
@LevLevitsky: หนึ่งในตัวอย่างการใช้ Mython คือ "การขยายโพรโทคอลเพื่อให้ตัวดำเนินการใด ๆ สามารถโอเวอร์โหลดได้is" หลังจากแสดงความคิดเห็นในรายการแล้วเขาก็เปลี่ยนเป็น "... แม้is(แต่ถ้าคุณบ้า")
abarnert

1
+1 แต่จะดียิ่งขึ้นถ้าคำตอบนี้รวมการอ้างอิง PEP 8 ที่คนอื่นทำ (รวมทั้งอธิบายว่าเพราะเหตุใดการตัดสินใจเบื้องหลัง PEP 8 จึงสมเหตุสมผลซึ่งทำอยู่แล้ว)
abarnert

3
@abarnert - ฉันไม่ทราบด้วยซ้ำว่า PEP 8 ได้ให้คำแนะนำที่นี่ ประเด็นก็คือพวกมันเป็นตัวดำเนินการที่แตกต่างกัน อาจจะมีกรณีที่object == Noneจริงเป็นสำนวนที่ถูกต้อง ( แต่ผมไม่สามารถคิดใด ๆ ที่ปิดด้านบนของหัวของฉัน) คุณแค่ต้องรู้ว่าคุณกำลังทำอะไรอยู่
mgilson

127

isเป็นที่ต้องการโดยทั่วไปเมื่อเปรียบเทียบออบเจ็กต์โดยพลการกับซิงเกิลตันเช่นNoneนั้นเพราะเร็วกว่าและคาดเดาได้มากกว่า isมักจะเปรียบเทียบโดยเอกลักษณ์ของวัตถุในขณะที่สิ่งที่==จะทำขึ้นอยู่กับชนิดที่แน่นอนของตัวถูกดำเนินการและแม้กระทั่งในการสั่งซื้อของพวกเขา

ข้อเสนอแนะนี้ได้รับการสนับสนุนโดยPEP 8ซึ่งระบุอย่างชัดเจนว่า "การเปรียบเทียบกับซิงเกิลตันเช่นไม่มีควรทำด้วยisหรือis notไม่ต้องใช้ตัวดำเนินการความเสมอภาค"


6
ขอบคุณสำหรับการโพสต์สิ่งนี้; คำตอบที่ได้รับการยอมรับทำให้บางจุดที่น่าสนใจ แต่คุณตอบคำถามได้โดยตรงมากขึ้น
ลุคเดวิส

ดูเหมือนว่าแปลกที่จะพึ่งพารายละเอียดการใช้งานเป็นหลัก ทำไมฉันถึงต้องสนใจว่า NoneType นั้นมีอินสแตนซ์จำนวนเท่าไร
BallpointBen

@BallpointBen เพราะมันไม่ได้รายละเอียดการดำเนินงาน - มีเพียงหนึ่งวัตถุภายใต้อย่างต่อเนื่องทั่วโลกNone Noneหากมีสิ่งใดNoneTypeเป็นรายละเอียดการดำเนินการเพราะNoneซิงเกิลต้องมีบางประเภท (ความจริงที่ว่าคุณไม่สามารถสร้างอินสแตนซ์ของประเภทนี้เป็นสิ่งบ่งชี้ที่ดีว่าอินสแตนซ์หนึ่งตัวนั้นตั้งใจให้เป็นแบบซิงเกิล)
user4815162342

@ BallpointBen ฉันคิดว่าประเด็นสำคัญคือ Python มีแนวคิดที่ชัดเจนเกี่ยวกับเอกลักษณ์ของวัตถุ หากคุณต้องการที่จะตรวจสอบว่าวัตถุเปรียบเทียบเท่ากับการโดยวิธีการใช้งานทั้งหมดNone obj == Noneหากคุณต้องการที่จะตรวจสอบว่าวัตถุคือ การใช้None obj is Noneจุดของข้อเสนอแนะ PEP 8 (และคำตอบนี้) คือคนส่วนใหญ่ต้องการสิ่งหลังเมื่อพวกเขาต้องการตรวจสอบไม่มีและมันก็เกิดขึ้นได้เร็วขึ้นและชัดเจนขึ้น
user4815162342

Noneก็แตกต่างจากวัตถุที่ถูกแคชเช่น0และจำนวนเต็มขนาดเล็กอื่น ๆ ซึ่งการแคชจริงๆเป็นรายละเอียดการใช้งาน ความแตกต่างคือจำนวนเต็มมีค่าที่แท้จริงซึ่งให้คุณสมบัติและสามารถคำนวณได้ ในอีกด้านหนึ่งNoneไม่มีรัฐใด ๆ มันเป็นเพียงตัวตนที่สำคัญและทำให้เป็นพิเศษ
user4815162342

11

PEP 8 กำหนดว่าจะเป็นการดีกว่าหากใช้ตัวisดำเนินการเมื่อเปรียบเทียบซิงเกิลตัน

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