Stałe klasowe w Pythonie


128

W Pythonie chcę, aby klasa miała pewne „stałe” (praktycznie zmienne), które będą wspólne dla wszystkich podklas. Czy można to zrobić za pomocą przyjaznej składni? Obecnie używam:

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

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

i zastanawiam się, czy istnieje lepszy sposób na zrobienie tego lub sposób na zrobienie tego bez konieczności pisania „Animal”. przed rozmiarami. Dzięki! edycja: zapomniałem wspomnieć, że koń dziedziczy po zwierzęciu.


16
Nie jest to pełna odpowiedź, ale jeśli SIZESnigdy się nie zmieni, zdecydowanie użyj krotki zamiast listy. Tak("Huge","Big","Medium","Small")
— jamylak

Wygląda na to, że naprawdę szukasz tutaj wyliczenia
— Eric

Odpowiedzi:


141

Ponieważ Horsejest to podklasa Animal, możesz po prostu zmienić

print(Animal.SIZES[1])

z

print(self.SIZES[1])

Mimo to musisz pamiętać, że SIZES[1]oznacza to „duży”, więc prawdopodobnie mógłbyś ulepszyć swój kod, wykonując coś takiego:

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

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

Alternatywnie, można utworzyć klasy pośrednich: HugeAnimal, BigAnimal, i tak dalej. Byłoby to szczególnie pomocne, gdyby każda klasa zwierząt miała inną logikę.


SIZE_BIG = ["BigOne", "BigTwo"] powinienem używać tego typu stałej.
— Lova Chittumuri

17

Możesz dostać się SIZESza pomocą self.SIZES(w metodzie instancji) lub cls.SIZES(w metodzie klasowej).

W każdym razie musisz wyraźnie określić, gdzie znaleźć SIZES. Alternatywą jest umieszczenie SIZESmodułu zawierającego klasy, ale wtedy musisz zdefiniować wszystkie klasy w jednym module.


Koń jest rzeczywiście podklasą zwierzęcia. Właściwie jest całkowicie możliwe użycie self.SIZES [1] zamiast Animal.SIZES [1].
— betabandido

@betabandido: OP poprawił pytanie. Odpowiednio zaktualizuje odpowiedź.
— Fred Foo

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

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

Możesz również uzyskać dostęp przez siebie, np. „self.HUGE” lub „self.BIG”. To działałoby tylko wewnętrznie w klasie.
— cevaris

4

Rozwijając odpowiedź betabandido, możesz napisać funkcję, która wstrzyknie atrybuty jako stałe do modułu:

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_BIGpoza klasą będzie to samo? Czy będzie można go edytować Animal.SIZE_HUGE = 'Small'?
— Crusader
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.