'id' เป็นชื่อตัวแปรที่ไม่ดีใน Python


141

ทำไมการตั้งชื่อตัวแปรidใน Python จึงไม่ดี


33
คนส่วนใหญ่ใส่เครื่องหมายขีดล่างเพื่อระบุว่าขัดแย้งกับบิลด์ / คีย์เวิร์ด: id_, map_, list_, filter_, ฯลฯ
cdleary

3
IDวิธีการแก้ปัญหาส่อเสียดมากขึ้นจะใช้ตัวแปร
Simon Kuang

46
คำถามที่ดีกว่าคือ ... อัจฉริยะใดที่คิดว่าใช้ชื่อสามัญทั่วไปสำหรับฟังก์ชันในตัวเป็นความคิดที่ดี
พื้นฐาน

คำตอบ:


143

id() เป็นพื้นฐานในตัว:

ความช่วยเหลือเกี่ยวกับฟังก์ชั่นidในตัวในโมดูล __builtin__:

id(...)

    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory
    address.)

โดยทั่วไปการใช้ชื่อตัวแปรที่ทำให้เกิดคำหลักหรือฟังก์ชันในตัวในภาษาใด ๆ เป็นความคิดที่ไม่ดีแม้ว่าจะได้รับอนุญาตก็ตาม


3
ตกลงสำหรับ 'id' คุณถูก แต่ความคิดเห็น "โดยทั่วไป ... " ยังคงใช้อยู่คุณไม่คิดเหรอ?
Kevin Little

5
ฉันจะหลีกเลี่ยงมันสำหรับโมดูลกลมอย่างแน่นอน สำหรับตัวแปรที่ จำกัด อยู่ในขอบเขตของระบบดังนั้นคุณสามารถเห็นฟังก์ชั่นเดียวกันไม่จำเป็นต้องใช้ตัวบิวอินมันไม่ใช่สิ่งที่ฉันต้องกังวล
bobince

@Caramdir: จับได้ดีidถูกกำหนดให้ลบในครั้งเดียว แต่ในที่สุดพวกเขาก็ตัดสินใจที่จะไม่ลบ ฉันไม่สามารถแก้ไขความคิดเห็นดั้งเดิมของฉันได้อีกต่อไปดังนั้นฉันจะลบมันเพื่อหลีกเลี่ยงความสับสนในอนาคต
Eli Courtwright

20
@EliCourtwright ฉันหวังว่าพวกเขาจะลบมันออก เป็นวิธีที่มีชื่อไม่ดีเลย! ชื่อสามัญทั่วไปที่ใช้ในหลายพันแห่ง (ที่บริบทให้ความหมาย) ดังนั้นใครบางคนตัดสินใจที่จะใช้มันเป็นชื่อระดับโลกที่ไม่มีบริบท?
พื้นฐาน

2
น่าอัศจรรย์ของ Google งูหลามตัวเอง regex กวดวิชา ( developers.google.com/edu/python/regular-expressions ) str = 'an example word:cat!!'การใช้งาน มีอะไรใน PEPs ใด ๆ ที่ระบุว่าไม่ทำเช่นนี้?
คำจาก

57

ในPEP 8 - คู่มือสไตล์สำหรับรหัส Pythonคำแนะนำต่อไปนี้จะปรากฏในส่วนคำอธิบาย: รูปแบบการตั้งชื่อ :

  • single_trailing_underscore_ : ใช้โดยการประชุมเพื่อหลีกเลี่ยงข้อขัดแย้งกับคำหลัก Python เช่น

    Tkinter.Toplevel(master, class_='ClassName')

ดังนั้นเพื่อตอบคำถามตัวอย่างที่ใช้แนวทางนี้คือ:

id_ = 42

การใส่เครื่องหมายขีดล่างในชื่อตัวแปรทำให้เจตนาชัดเจน (สำหรับผู้ที่คุ้นเคยกับคำแนะนำใน PEP 8)


1
นี้ไม่ได้ตอบคำถามที่เกิดขึ้นจริง แต่ +1 สำหรับ PEP-8 ประชุมการตั้งชื่อ
ege

คำแนะนำที่ดี แต่idเป็น builtin ไม่ใช่คำหลักและสิ่งนี้ไม่ได้อธิบายว่าทำไมมันจึงไม่ดีที่จะสร้างเงาในตัว
wjandrea

51

idเป็นฟังก์ชันในตัวที่ให้ข้อมูลประจำตัวของวัตถุ (ซึ่งเป็นที่อยู่หน่วยความจำใน CPython) หากคุณตั้งชื่อหนึ่งในฟังก์ชั่นของidคุณคุณจะต้องพูดbuiltins.idเพื่อรับต้นฉบับ (หรือ__builtins__.idใน CPython) การเปลี่ยนชื่อidทั่วโลกทำให้สับสนในทุกเรื่องยกเว้นสคริปต์ตัวเล็ก

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

ตัวอย่าง:

def numbered(filename):
    with open(filename) as file:
        for i, input in enumerate(file):
            print("%s:\t%s" % (i, input), end='')

บิวด์อินบางส่วนมีชื่อที่ดึงดูด:

  • id
  • file
  • list, dict
  • map
  • all, any
  • complex, int
  • dir
  • input
  • slice
  • buffer
  • sum
  • min, max
  • object

8
PEP 8ซึ่งได้รับการอัปเดตตั้งแต่วันที่ 01 ส.ค. 2556 ขอแนะนำให้หลีกเลี่ยงความสับสนที่อาจเกิดขึ้นโดยเพียงต่อท้าย_ชื่อตัวแปร โปรดดูคำตอบของฉัน
DavidRR

1
เป็นที่น่าสังเกตว่าidฟังก์ชันที่ส่งคืนที่อยู่หน่วยความจำของวัตถุนั้นเป็นรายละเอียดการใช้งานของ CPython นอกจากนี้ยังเป็นที่น่าสังเกตว่าฟังก์ชั่นนี้จะต้องส่งคืนหมายเลขที่แตกต่างกันสำหรับวัตถุที่ยังหลงเหลืออยู่สองตัวเท่านั้น หากวัตถุเป็นขยะที่เก็บรวบรวม id ของมันอาจถูกนำมารีไซเคิล
Zac Crites

@Zac ขอบคุณ! ฉันแก้ไขคำตอบเพื่อเพิ่มจุดนั้นเกี่ยวกับที่อยู่หน่วยความจำและลิงก์เพื่อให้ผู้คนสามารถอ่านเพิ่มเติมได้
wjandrea

42

ฉันอาจพูดบางอย่างที่ไม่เป็นที่นิยมที่นี่: id()เป็นฟังก์ชันในตัวที่ค่อนข้างพิเศษซึ่งไม่ค่อยได้ใช้ในตรรกะทางธุรกิจ ดังนั้นฉันไม่เห็นปัญหาในการใช้มันเป็นชื่อตัวแปรในฟังก์ชั่นที่แน่นและเขียนได้ดีซึ่งเป็นที่ชัดเจนว่า id ไม่ได้หมายถึงฟังก์ชั่นในตัว


1
เพื่อตอบสนองต่อ:> id เป็นฟังก์ชันในตัวที่ค่อนข้างพิเศษซึ่งไม่ค่อยได้ใช้ใน> ตรรกะทางธุรกิจ ดังนั้นฉันจึงไม่เห็น> ปัญหาในการใช้มันเป็นตัวแปร> ชื่อในฟังก์ชั่นที่แน่นและเขียนดี แต่ถ้าเป็นที่ชัดเจนว่า id> ไม่ได้หมายถึงฟังก์ชั่นในตัว แม้ว่านี่จะเป็นความจริง แต่ก็เป็นความคิดที่ดีที่จะเจาะจงชื่อตัวแปรนี้มากกว่า "id" มีหลายสิ่งที่มี ID (โดยเฉพาะถ้าคุณกำลังทำงานกับ RDBMS) และในฐานะบรรทัดที่สองของThe Zen of Pythonของ Tim Peters บอกเราว่า> ชัดเจนกว่าดีกว่านัย ดูส่วนที่เหลือด้วยการวิ่ง:import this
Ross

9
ฉันจะยังคงหลีกเลี่ยงถ้าเป็นไปได้แม้ว่า แม้ว่าจะไม่มีเหตุผลอื่นนอกจากจะไม่ได้ยินเพื่อนร่วมงานบ่น :-)
Jason Baker

1
ฉันเห็นด้วยอย่างสมบูรณ์: การตั้งชื่อตัวแปร "id" ในฟังก์ชั่นขนาดเล็ก (และขอบเขต) จึงไม่เป็นอันตราย คนน้อยมากที่ใช้idbuiltin อยู่แล้ว ที่กล่าวว่ามันใช้เวลาสักครู่เมื่อเพื่อนร่วมงานของฉันทำลายlistตัวบิวอินด้วยตัวแปรท้องถิ่น ดังนั้นกฎทั่วไปที่คนอื่นพูดถึงยังคงสมเหตุสมผล
silviot

5

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


2

idเป็นฟังก์ชันในตัวใน Python การกำหนดค่าที่idจะแทนที่ฟังก์ชัน ดีที่สุดคือการเพิ่มคำนำหน้าเช่นเดียวกับในหรือใช้ในมูลค่าที่แตกต่างกันในขณะที่some_idID

ฟังก์ชั่นบิวด์อินจะใช้อาร์กิวเมนต์ตัวเดียวและส่งกลับจำนวนเต็มสำหรับที่อยู่หน่วยความจำของวัตถุที่คุณผ่าน (เป็น CPython)

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760

2
โปรดทราบว่าคุณสามารถตั้งชื่อแอตทริบิวต์คลาสหรือเมธอด 'id' ซึ่งจะไม่แตะฟังก์ชั่นในตัว
Toni Ruža


0

อื่น ๆ ได้กล่าวว่ามันทำให้เกิดความสับสน แต่ผมต้องการที่จะขยายตัวในเหตุผล นี่คือตัวอย่างจากเรื่องจริง โดยทั่วไปฉันเขียนคลาสที่ใช้idพารามิเตอร์ แต่ลองใช้ builtin ในidภายหลัง

class Employee:
    def __init__(self, name, id):
        """Create employee, with their name and badge id."""
        self.name = name
        self.id = id
        # ... lots more code, making you forget about the parameter names
        print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))

tay = Employee('Taylor Swift', 1985)

ผลลัพธ์ที่คาดหวัง:

Created Employee 'Taylor Swift' at 0x7efde30ae910

เอาท์พุทที่แท้จริง:

Traceback (most recent call last):
  File "company.py", line 9, in <module>
    tay = Employee('Taylor Swift', 1985)
  File "company.py", line 7, in __init__
    print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
TypeError: 'int' object is not callable

ฮะ? ฉันพยายามโทรหา int ที่ไหน นั่นคือทั้งหมดที่มีอยู่ภายใน ...

ถ้าฉันตั้งชื่อbadge_idหรือid_ฉันจะไม่ได้มีปัญหานี้


-6

เนื่องจาก python เป็นภาษาแบบไดนามิกจึงไม่ใช่ความคิดที่ดีที่จะให้ตัวแปรและฟังก์ชั่นชื่อเดียวกัน id () เป็นฟังก์ชั่นในไพ ธ อนดังนั้นจึงไม่แนะนำให้ใช้ตัวแปรชื่อ id โดยคำนึงถึงว่ามันใช้กับทุกฟังก์ชั่นที่คุณอาจใช้ ... ตัวแปรไม่ควรมีชื่อเดียวกับฟังก์ชั่น


3
"เนื่องจากไพ ธ อนเป็นภาษาไดนามิกจึงไม่ควรให้ตัวแปรและฟังก์ชั่นชื่อเดียวกัน" - คุณไม่สามารถกำหนดตัวแปรและฟังก์ชั่นชื่อเดียวกันได้ ไม่มีอะไรเกี่ยวข้องกับมันเป็นภาษาแบบไดนามิก หากคุณหมายถึงการให้คุณสมบัติชื่อเดียวกับวัตถุอื่นในขอบเขตเดียวกันฉันก็ไม่เห็นด้วย คุณอาจมีคลาสเรียกว่า "คีย์" อินสแตนซ์ของคลาสนั้นเรียกว่า "คีย์" และคุณสมบัติของวัตถุอื่นที่เรียกว่า "คีย์" เช่น "door.key"
Purrell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.