Konstanta kelas dalam python

128

Dalam python, saya ingin kelas memiliki beberapa "konstanta" (praktis, variabel) yang akan umum di semua subclass. Apakah ada cara untuk melakukannya dengan sintaks yang ramah? Saat ini saya menggunakan:

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

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

dan saya bertanya-tanya apakah ada cara yang lebih baik untuk melakukannya atau cara melakukannya tanpa harus menulis "Animal." sebelum ukuran. Terima kasih! sunting: lupa menyebutkan bahwa kuda mewarisi dari binatang.

nodwj
sumber
16
Bukan jawaban lengkap tetapi Jika SIZEStidak pernah berubah, pasti menggunakan tuple bukan daftar. Seperti begitu("Huge","Big","Medium","Small")
jamylak
Sepertinya Anda benar-benar mengejar enum di sini
Eric

Jawaban:

141

Karena Horseini adalah subkelas dari Animal, Anda bisa mengubahnya

print(Animal.SIZES[1])

dengan

print(self.SIZES[1])

Namun, Anda harus ingat itu SIZES[1]berarti "besar", jadi mungkin Anda dapat meningkatkan kode Anda dengan melakukan sesuatu seperti:

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

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

Atau, Anda bisa membuat kelas menengah: HugeAnimal, BigAnimal, dan sebagainya. Itu akan sangat membantu jika setiap kelas hewan akan mengandung logika yang berbeda.

betabandido
sumber
SIZE_BIG = ["BigOne", "BigTwo"] saya harus menggunakan jenis konstanta ini.
Lova Chittumuri
17

Anda dapat SIZESmenggunakan self.SIZES(dalam metode instance) atau cls.SIZES(dalam metode kelas).

Bagaimanapun, Anda harus secara eksplisit tentang di mana menemukannya SIZES. Alternatifnya adalah dengan memasukkan SIZESmodul yang berisi kelas-kelas, tetapi kemudian Anda perlu mendefinisikan semua kelas dalam satu modul.

Fred Foo
sumber
Kuda memang merupakan subkelas Hewan. Sebenarnya, sangat mungkin untuk menggunakan self.SIZES [1] bukan Animal.SIZES [1].
betabandido
@betabandido: OP mengoreksi pertanyaan. Akan memperbarui jawaban yang sesuai.
Fred Foo
12
class Animal:
    HUGE = "Huge"
    BIG = "Big"

class Horse:
    def printSize(self):
        print(Animal.HUGE)
ya
sumber
Anda juga dapat mengakses melalui diri sendiri, mis. "self.HUGE" atau "self.BIG". Ini hanya akan bekerja secara internal di dalam kelas.
cevaris
4

Memperluas jawaban betabandido, Anda bisa menulis fungsi untuk menyuntikkan atribut sebagai konstanta ke dalam modul:

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
Matthew Trevor
sumber
print SIZE_BIGdi luar kelas akan sama? Apakah ini dapat diedit Animal.SIZE_HUGE = 'Small'?
Crusader