คำถามที่ฉันกำลังจะถามดูเหมือนจะซ้ำกันกับการใช้ __new__ และ __init__ของPython? แต่อย่างไรก็ตามก็ยังไม่ชัดเจนสำหรับฉันว่าความแตกต่างในทางปฏิบัติระหว่าง__new__
และ__init__
คืออะไร
ก่อนที่คุณจะรีบบอกฉันว่า__new__
มีไว้สำหรับสร้างวัตถุและ__init__
มีไว้สำหรับการเริ่มต้นอ็อบเจ็กต์ขอฉันพูดให้ชัดเจน: ฉันเข้าใจ ในความเป็นจริงความแตกต่างนั้นค่อนข้างเป็นธรรมชาติสำหรับฉันเนื่องจากฉันมีประสบการณ์ใน C ++ ที่เรามีการจัดวางใหม่ซึ่งแยกการจัดสรรอ็อบเจ็กต์ออกจากการเริ่มต้นในทำนองเดียวกัน
หลาม C API กวดวิชาอธิบายเช่นนี้
สมาชิกใหม่มีหน้าที่สร้างอ็อบเจ็กต์ประเภท (ซึ่งตรงข้ามกับการกำหนดค่าเริ่มต้น) มันถูกเปิดเผยใน Python เป็น
__new__()
วิธีการ ... เหตุผลหนึ่งที่จะใช้วิธีการใหม่เพื่อให้มั่นใจค่าเริ่มต้นของตัวแปรเช่น
ใช่แล้ว - ฉันได้อะไร__new__
แต่ถึงอย่างนั้นฉันก็ยังไม่เข้าใจว่าทำไมมันถึงมีประโยชน์ใน Python ตัวอย่างที่ระบุบอกว่า__new__
อาจมีประโยชน์หากคุณต้องการ "รับรองค่าเริ่มต้นของตัวแปรอินสแตนซ์" ก็ใช่ว่า__init__
จะทำอะไร?
ในบทช่วยสอน C API ตัวอย่างจะแสดงที่สร้าง Type ใหม่ (เรียกว่า "Noddy") และกำหนด__new__
ฟังก์ชันของ Type ประเภท Noddy ประกอบด้วยสมาชิกสตริงที่เรียกว่าfirst
และสมาชิกสตริงนี้เริ่มต้นเป็นสตริงว่างดังนี้:
static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
.....
self->first = PyString_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
.....
}
โปรดทราบว่าหากไม่มี__new__
วิธีการที่กำหนดไว้ที่นี่เราจะต้องใช้PyType_GenericNew
ซึ่งเพียงแค่เริ่มต้นสมาชิกตัวแปรอินสแตนซ์ทั้งหมดเป็น NULL ดังนั้นประโยชน์เพียงอย่างเดียวของ__new__
วิธีนี้คือตัวแปรอินสแตนซ์จะเริ่มต้นเป็นสตริงว่างซึ่งตรงข้ามกับ NULL แต่เหตุใดสิ่งนี้จึงมีประโยชน์เนื่องจากหากเราใส่ใจในการตรวจสอบให้แน่ใจว่าตัวแปรอินสแตนซ์ของเราเริ่มต้นเป็นค่าเริ่มต้นบางอย่างเราสามารถทำได้ใน__init__
วิธีนี้
__new__
ไม่ใช่สำเร็จรูปเนื่องจากต้นแบบไม่เคยเปลี่ยนแปลง บางครั้งคุณต้องแทนที่รหัสนั้นด้วยสิ่งที่แตกต่างออกไป