ค่าคงที่ของคลาสใน python


129

ใน python ฉันต้องการให้คลาสมี "ค่าคงที่" (ตัวแปรในทางปฏิบัติ) ซึ่งจะพบได้ทั่วไปในคลาสย่อยทั้งหมด มีวิธีทำด้วยไวยากรณ์ที่เป็นมิตรหรือไม่? ตอนนี้ฉันใช้:

class Animal:
    SIZES=["Huge","Big","Medium","Small"]

class Horse(Animal):
    def printSize(self):
        print(Animal.SIZES[1])

และฉันสงสัยว่ามีวิธีที่ดีกว่านี้หรือวิธีที่จะทำได้โดยไม่ต้องเขียนว่า "สัตว์" ก่อนขนาด ขอบคุณ! แก้ไข: ลืมบอกว่าม้าสืบทอดมาจากสัตว์


16
ไม่ใช่คำตอบที่สมบูรณ์ แต่ถ้าSIZESไม่เคยเปลี่ยนแปลงให้ใช้ทูเพิลแทนรายการ เช่นนั้น("Huge","Big","Medium","Small")
jamylak

ดูเหมือนว่าคุณจะตามหลัง enum ที่นี่จริงๆ
Eric

คำตอบ:


143

เนื่องจากHorseเป็นคลาสย่อยAnimalคุณสามารถเปลี่ยนได้

print(Animal.SIZES[1])

กับ

print(self.SIZES[1])

ถึงกระนั้นคุณต้องจำไว้ว่านั่นSIZES[1]หมายถึง "ใหญ่" ดังนั้นคุณอาจปรับปรุงโค้ดของคุณได้โดยทำสิ่งต่อไปนี้

class Animal:
    SIZE_HUGE="Huge"
    SIZE_BIG="Big"
    SIZE_MEDIUM="Medium"
    SIZE_SMALL="Small"

class Horse(Animal):
    def printSize(self):
        print(self.SIZE_BIG)

หรือคุณสามารถสร้างชั้นเรียนระดับกลาง: HugeAnimal, BigAnimalและอื่น ๆ นั่นจะเป็นประโยชน์อย่างยิ่งหากสัตว์แต่ละชั้นมีตรรกะที่แตกต่างกัน


SIZE_BIG = ["BigOne", "BigTwo"] ฉันจะใช้ค่าคงที่ประเภทนี้
Lova Chittumuri

18

คุณสามารถเข้าถึงได้SIZESโดยใช้self.SIZES(ในวิธีการอินสแตนซ์) หรือcls.SIZES(ในวิธีการคลาส)

ไม่ว่าในกรณีใดคุณจะต้องมีความชัดเจนว่าจะหาได้จากที่SIZESใด อีกทางเลือกหนึ่งคือใส่SIZESโมดูลที่มีคลาส แต่คุณต้องกำหนดคลาสทั้งหมดในโมดูลเดียว


ม้าเป็นคลาสย่อยของสัตว์ จริงๆแล้วมันเป็นไปได้อย่างสมบูรณ์แบบที่จะใช้ self.SIZES [1] แทน Animal.SIZES [1]
betabandido

@betabandido: OP แก้ไขคำถาม จะอัพเดทคำตอบตามนั้น.
Fred Foo

12
class Animal:
    HUGE = "Huge"
    BIG = "Big"

class Horse:
    def printSize(self):
        print(Animal.HUGE)

นอกจากนี้คุณสามารถเข้าถึงได้ด้วยตนเองเช่น "self.HUGE" หรือ "self.BIG". สิ่งนี้จะใช้ได้ภายในชั้นเรียนเท่านั้น
cevaris

4

เมื่อขยายคำตอบของ betabandido คุณสามารถเขียนฟังก์ชันเพื่อฉีดแอตทริบิวต์เป็นค่าคงที่ลงในโมดูล:

def module_register_class_constants(klass, attr_prefix):
    globals().update(
        (name, getattr(klass, name)) for name in dir(klass) if name.startswith(attr_prefix)
    )

class Animal(object):
    SIZE_HUGE = "Huge"
    SIZE_BIG = "Big"

module_register_class_constants(Animal, "SIZE_")

class Horse(Animal):
    def printSize(self):
        print SIZE_BIG

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