ตัวเลือกการตรึงและการเปรียบเทียบ
สร้าง dataclass ที่เปลี่ยนแปลงไม่ได้และเรียงลำดับได้
ตัวเลือกการตรึงและการเปรียบเทียบ เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
ตัวเลือกของตัวตกแต่ง
ตัวตกแต่ง @dataclass รับอาร์กิวเมนต์คำสำคัญที่ควบคุมว่าจะสร้างเมธอดใดบ้าง ตัวเลือกที่มีประโยชน์ที่สุดคือ frozen และ order
frozen=Trueทำให้อินสแตนซ์เปลี่ยนแปลงไม่ได้order=Trueเพิ่มตัวดำเนินการเปรียบเทียบ
คลาสข้อมูลแบบแช่แข็ง
เมื่อใช้ frozen=True คลาสที่สร้างขึ้นจะป้องกันการกำหนดค่าแอตทริบิวต์หลังการสร้าง อะไรก็ตามที่พยายามทำเช่นนั้นจะส่ง FrozenInstanceError
from dataclasses import dataclass, FrozenInstanceError
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
try:
p.x = 99
except FrozenInstanceError as e:
print('Cannot modify:', e)เหตุใดการเปลี่ยนแปลงไม่ได้จึงมีประโยชน์
ออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ทำความเข้าใจได้ง่ายกว่า เพราะค่าของออบเจ็กต์จะไม่เปลี่ยนหลังสร้าง จึงสามารถใช้ร่วมกันระหว่างฟังก์ชันและเธรดได้อย่างปลอดภัย นอกจากนี้ยังใช้เป็นคีย์ของพจนานุกรมและสมาชิกของเซตได้อย่างปลอดภัย
แบบแช่แข็งหมายถึงแฮชได้
ดาต้าคลาสแบบแช่แข็งจะแฮชได้เป็นค่าเริ่มต้น คุณจึงใช้อินสแตนซ์ในเซตหรือเป็นคีย์ของดิกชันนารีได้ ส่วนดาต้าคลาสที่เปลี่ยนแปลงได้จะไม่สามารถแฮชได้ เว้นแต่คุณจะเลือกเปิดใช้ความสามารถนี้
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
seen = {Point(0, 0), Point(1, 1), Point(0, 0)}
print(len(seen))การแทนที่ค่าแบบแช่แข็ง
เนื่องจากคุณไม่สามารถเปลี่ยนแปลงอินสแตนซ์แบบแช่แข็งได้ ให้ใช้ dataclasses.replace() เพื่อสร้างสำเนาที่แก้ไขแล้ว อินสแตนซ์เดิมจะไม่ถูกเปลี่ยนแปลง
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
q = replace(p, y=99)
print(p)
print(q)ดาต้าคลาสที่จัดลำดับ
โดยค่าเริ่มต้น ดาต้าคลาสรองรับเพียง == เท่านั้น เพิ่ม order=True เพื่อสร้าง <, <=, > และ >= เพิ่มเติม
from dataclasses import dataclass
@dataclass(order=True)
class Version:
major: int
minor: int
print(Version(1, 2) < Version(1, 5))
print(Version(2, 0) > Version(1, 9))การเปรียบเทียบลำดับทำงานอย่างไร
การจัดลำดับจะเปรียบเทียบฟิลด์ในรูปของทูเพิลจากซ้ายไปขวา ตามลำดับที่ประกาศไว้ ฟิลด์แรกมีความสำคัญสูงสุด
from dataclasses import dataclass
@dataclass(order=True)
class Version:
major: int
minor: int
# major compared first, then minor
print(Version(1, 9) < Version(2, 0))การเรียงลำดับอินสแตนซ์ของดาต้าคลาส
เนื่องจากดาต้าคลาสที่จัดลำดับจะกำหนดตัวดำเนินการเปรียบเทียบไว้ คุณจึงเรียงลำดับรายการของอินสแตนซ์เหล่านี้ได้โดยตรงด้วย sorted()
from dataclasses import dataclass
@dataclass(order=True)
class Score:
points: int
name: str
data = [Score(50, 'B'), Score(90, 'A'), Score(70, 'C')]
for s in sorted(data):
print(s)การควบคุมคีย์การเรียงลำดับ
หากต้องการเรียงลำดับด้วยสิ่งอื่นนอกเหนือจากลำดับฟิลด์ตามธรรมชาติ ให้ใส่ฟิลด์การเรียงลำดับที่ซ่อนไว้เป็นฟิลด์แรกด้วย field(init=False) แล้วกำหนดค่าให้ฟิลด์นั้นใน __post_init__ คุณสามารถแยกฟิลด์อื่นออกจากการเปรียบเทียบด้วย compare=False
from dataclasses import dataclass, field
@dataclass(order=True)
class Item:
sort_index: int = field(init=False, repr=False)
name: str = field(compare=False, default='')
priority: int = 0
def __post_init__(self):
self.sort_index = self.priority
print(Item(name='b', priority=2) > Item(name='a', priority=1))การรวมแบบแช่แข็งกับการจัดลำดับ
คุณสามารถรวมตัวเลือกต่าง ๆ ได้ ดาต้าคลาสที่ทั้งแช่แข็งและจัดลำดับได้จะเป็นชนิดค่าที่ไม่เปลี่ยนแปลงและเปรียบเทียบได้อย่างเหมาะสม เหมาะสำหรับคีย์ หมายเลขเวอร์ชัน หรือพิกัด
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class SemVer:
major: int
minor: int
patch: int
versions = {SemVer(1, 0, 0): 'stable'}
print(SemVer(1, 0, 0) < SemVer(1, 1, 0))
print(versions[SemVer(1, 0, 0)])eq และค่าเริ่มต้น
ตัวเลือก eq ควบคุมว่าจะสร้าง __eq__ หรือไม่ โดยค่าเริ่มต้นคือ True โปรดทราบว่า order=True ต้องใช้ร่วมกับ eq=True เนื่องจากการจัดลำดับอาศัยการตรวจสอบความเท่ากัน
from dataclasses import dataclass
@dataclass(eq=True)
class Tag:
name: str
print(Tag('x') == Tag('x'))
print(Tag('x') == Tag('y'))ตรวจสอบอย่างรวดเร็ว
จะเกิดอะไรขึ้นหากคุณกำหนดค่าให้ฟิลด์ของอินสแตนซ์ดาต้าคลาสแบบแช่แข็ง
สรุปทบทวน
คุณได้เรียนรู้การสร้างดาต้าคลาสที่ไม่เปลี่ยนแปลงและจัดลำดับได้
frozen=Trueป้องกันการเปลี่ยนแปลงและทำให้อินสแตนซ์แฮชได้- ใช้
replace()เพื่อสร้างสำเนาที่แก้ไขแล้ว order=Trueจะสร้างตัวดำเนินการเปรียบเทียบที่เปรียบเทียบฟิลด์ในรูปของทูเพิล- รวมทั้งสองตัวเลือกเพื่อสร้างชนิดค่าที่มั่นคง
คำถามที่พบบ่อย
บทเรียน “ตัวเลือกการตรึงและการเปรียบเทียบ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวเลือกการตรึงและการเปรียบเทียบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวเลือกการตรึงและการเปรียบเทียบ”
สร้าง dataclass ที่เปลี่ยนแปลงไม่ได้และเรียงลำดับได้ คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวเลือกการตรึงและการเปรียบเทียบ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม
ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกำหนด Dataclass
- ค่าเริ่มต้นและ field()
- ตัวเลือกการตรึงและการเปรียบเทียบ
- ไลบรารี attrs